diff options
856 files changed, 28935 insertions, 12890 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 89e8f4d146..f4c377b921 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -8,9 +8,9 @@ env: SCONS_CACHE_LIMIT: 4096 jobs: - linux-editor-mono: + linux-editor: runs-on: "ubuntu-20.04" - name: Editor w/ Mono (target=release_debug, tools=yes, tests=yes) + name: Editor (target=release_debug, tools=yes, tests=yes) steps: - uses: actions/checkout@v2 @@ -62,13 +62,13 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons tools=yes tests=yes target=release_debug module_mono_enabled=yes mono_glue=no + scons tools=yes tests=yes target=release_debug ls -l bin/ # Execute unit tests for the editor - name: Unit Tests run: | - ./bin/godot.linuxbsd.opt.tools.64.mono --test + ./bin/godot.linuxbsd.opt.tools.64 --test - uses: actions/upload-artifact@v2 with: @@ -76,9 +76,9 @@ jobs: path: bin/* retention-days: 14 - linux-editor-sanitizers: + linux-editor-sanitizers-mono: runs-on: "ubuntu-20.04" - name: Editor with sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes) + name: Editor w/ Mono and sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes) steps: - uses: actions/checkout@v2 @@ -130,13 +130,13 @@ jobs: env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ run: | - scons tools=yes tests=yes target=debug use_asan=yes use_ubsan=yes + scons tools=yes tests=yes target=debug module_mono_enabled=yes mono_glue=no use_asan=yes use_ubsan=yes ls -l bin/ # Execute unit tests for the editor - name: Unit Tests run: | - ./bin/godot.linuxbsd.tools.64s --test + ./bin/godot.linuxbsd.tools.64s.mono --test linux-template-mono: runs-on: "ubuntu-20.04" @@ -6,6 +6,7 @@ Anish Bhobe <anishbhobe@hotmail.com> Anutrix <numaanzaheerahmed@yahoo.com> Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com> Ariel Manzur <ariel@godotengine.org> +Ariel Manzur <ariel@godotengine.org> <puntob@gmail.com> Ariel Manzur <ariel@godotengine.org> <punto@godotengine.org> Ariel Manzur <ariel@godotengine.org> <ariel@okamstudio.com> Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini.local> @@ -25,6 +26,7 @@ Daniel J. Ramirez <djrmuv@gmail.com> Dominik 'dreamsComeTrue' JasiÅ„ski <dominikjasinski@o2.pl> Emmanuel Barroga <emmanuelbarroga@gmail.com> Eric M <itsjusteza@gmail.com> +Eric Rybicki <info@ericrybicki.com> <stratos695@googlemail.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com> Fabian <supagu@gmail.com> @@ -84,6 +86,7 @@ Mateo Kuruk Miccino <mateomiccino@gmail.com> Max Hilbrunner <m.hilbrunner@gmail.com> Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com> 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> Nils ANDRÉ-CHANG <nils@nilsand.re> @@ -97,7 +100,7 @@ Pieter-Jan Briers <pieterjan.briers+git@gmail.com> Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com> Poommetee Ketson <poommetee@protonmail.com> PrzemysÅ‚aw Gołąb (n-pigeon) <golab.przemyslaw@gmail.com> -RafaÅ‚ Mikrut <mikrutrafal54@gmail.com> +RafaÅ‚ Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com> Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de> Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@users.noreply.github.com> Ramesh Ravone <ramesh.maran443@gmail.com> @@ -116,11 +119,13 @@ Theo Hallenius <redsymbzone@hotmail.com> Thomas Herzog <therzog@mail.de> Thomas Herzog <therzog@mail.de> <thomas.herzog@mail.com> Thomas Herzog <therzog@mail.de> <thomas.herzog@simedis.com> +Tomasz Chabora <kobewi4e@gmail.com> Twarit <wtwarit@gmail.com> V.VamsiKrishna <vk@bsb.in> <vamsikrishna.v@gmail.com> Wilhem Barbier <nounoursheureux@openmailbox.org> <wilhem.b@free.fr> Wilhem Barbier <nounoursheureux@openmailbox.org> <schtroumps31@gmail.com> Will Nations <willnationsdev@gmail.com> yg2f <yoann@terminajones.com> +Yuri Sizov <yuris@humnom.net> <pycbouh@users.noreply.github.com> Zak Stam <zakscomputers@hotmail.com> Zher Huei Lee <lee.zh.92@gmail.com> diff --git a/AUTHORS.md b/AUTHORS.md index 97c66a014c..2faaf2d2c0 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -57,7 +57,9 @@ name is available. Daniel J. Ramirez (djrm) Daniel Rakos (aqnuep) dankan1890 + Danil Alexeev (dalexeev) David Sichma (DavidSichma) + David Snopek (dsnopek) Dharkael (lupoDharkael) Dmitry Koteroff (Krakean) Dominik JasiÅ„ski (dreamsComeTrue) @@ -99,6 +101,7 @@ name is available. Jérôme Gully (Nutriz) Jia Jun Chai (SkyLucilfer) Joan Fons Sanchez (JFonS) + Johannes Witt (HaSa1002) Johan Manuel (29jm) Joshua Grams (JoshuaGrams) Juan Linietsky (reduz) @@ -111,6 +114,7 @@ name is available. Leon Krause (leonkrause) Liz Haas (27thLiz) Lucien Menassol (Kanabenki) + Lyuma m4nu3lf Maganty Rushyendra (mrushyendra) Marcel Admiraal (madmiraal) @@ -135,6 +139,7 @@ name is available. MichiRecRoom (LikeLakers2) mrezai muiroc + Nathan Franke (nathanfranke) Nathan Lovato (NathanLovato) Nathan Warden (NathanWarden) Nils André-Chang (NilsIrl) @@ -188,6 +193,7 @@ name is available. Xavier Cho (mysticfall) yg2f (SuperUserNameMan) Yuri Roubinsky (Chaosus) + Yuri Sizov (pycbouh) Zak Stam (zaksnet) Zher Huei Lee (leezh) ZuBsPaCe diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index b9b15abf5d..ff24d18e6f 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -72,6 +72,11 @@ Copyright: 2008-2016, The Android Open Source Project 2002, Google, Inc. License: Apache-2.0 +Files: ./servers/physics_3d/collision_solver_3d_sat.cpp +Comment: Open Dynamics Engine +Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh +License: BSD-3-clause + Files: ./servers/physics_3d/gjk_epa.cpp ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -48,7 +48,6 @@ generous deed immortalized in the next stable release of Godot Engine. Digital Grows Dov Zimring Edward Flick - Franz Silva Gamechuck GameDev.net Hein-Pieter van Braam @@ -81,6 +80,7 @@ generous deed immortalized in the next stable release of Godot Engine. Acheron albinaask + Alvaro A Baena R Asher Glick Bernhard Werner Carlo Cabanilla @@ -89,6 +89,7 @@ generous deed immortalized in the next stable release of Godot Engine. Daniel James David Gehrig David Snopek + Don B Ed Morley Ellen Poe Florian Neumann @@ -103,7 +104,6 @@ generous deed immortalized in the next stable release of Godot Engine. Joan Fons Johnny IV Young Jon Woodward - Kai Klyden Karl Werf Klavdij Voncina Lex Steers @@ -136,6 +136,7 @@ generous deed immortalized in the next stable release of Godot Engine. Tom Langwaldt Tricky Fat Cat tukon + Vitaliy Sapronenko William Wold xagonist Xeno Coliseum @@ -144,17 +145,24 @@ generous deed immortalized in the next stable release of Godot Engine. Aaron Winter Adam Nakonieczny Adrian Adamiak + Aleksey Korotkevich Alexander J Maynard Alex de la Mare + Alexey Dyadchenko Alex Khayrullin alice gambrell Andreas Funke André Frélicot + Andrew Cunningham + Anm + Antanas Paskauskas Antoni Batchelli Arisaka Mayuki + Arthur S. Muszynski Aubin Detrez Barugon Ben Botwin + Caleb Sizemore Can Eris Charlie Whitfield Chase Taranto @@ -166,16 +174,19 @@ generous deed immortalized in the next stable release of Godot Engine. Conrad Curry Craig Ostrin Craig Smith + Cristopher D + dan didenko Darrian Little + Dennis Belfrage Dev To be curious Digital Denizen + Dimitri Nüscheler Donn Eddy Easypete Edgar Sun Eugenio Hugo Salgüero Jáñez flesk - Francisco Arámburo F S Gabrielius VaiÅ¡kÅ«nas Gary Hulst @@ -189,11 +200,14 @@ generous deed immortalized in the next stable release of Godot Engine. Horváth Péter Hu Hund Idilio Alfaro + Jake Burga James Couzens Jared Jared White + Jesús Chicharro Joel Fivat Joel Höglund + Johnathan Kupferer Jose Malheiro Joseph Crane Joshie Sparks @@ -208,10 +222,12 @@ generous deed immortalized in the next stable release of Godot Engine. Kelteseth kickmaniac kinfox - kuku + Kos Lachie Lain Ballard + Laszlo Kiss Leo Fidel R Liban + Liam Smyth Luc-Frédéric Langis luka duren MadScientistCarl @@ -220,17 +236,23 @@ generous deed immortalized in the next stable release of Godot Engine. Marcus Richter Marisa Clardy Mark Barrett + Mark Diaz Markus Fehr Martin Eigel Martin Kotz Martin Soucek Matt Eunson Matt Greene + Matthias Toepp + medecau Michael Michael Dürwald + Michael Noll + Michael Policastro MikadoSC MuffinManKen Nick Abousselam + Nick Barovic Oliver Dick Oscar Campos Patrick Brock @@ -245,32 +267,37 @@ generous deed immortalized in the next stable release of Godot Engine. Raymond Harris Raz A Ricardo Alcantara + Robert Larnach Robert Willes Rob McInroy Rocknight Studios Rodrigo Favarete Ronnie Ashlock Ronny Mühle - Ryan Wilson + Ryan Scott + Ryszard Sommefeldt Samuel Judd Scott Pilet Sean Morgan + Sebastian Hutter Sébastien Serban Serafimescu Sergey Minakov Shishir Tandale SKison + Song Junwoo spilldata Stephan Hennion Steven Landow Stoned Xander - TheLevelOfDetail . + TheLevelOfDetail Thomas Bjarnelöf Thomas Kurz Tim Howard + tinyBigGAMES LLC Tobias Bocanegra - Trent Fehl Turntsnaco + tweaklab Valryia Vincent Cloutier Vlad Ceru Opran @@ -287,7 +314,6 @@ generous deed immortalized in the next stable release of Godot Engine. ## Silver donors 1D_Inc - Aaron Passchier Abraham Haskins Adam Adam Brunnmeier @@ -305,24 +331,24 @@ generous deed immortalized in the next stable release of Godot Engine. AJ Austinson Aki Mimoto Alan Beauchamp + Alberto Vilches Albin Jonasson Svärdsby Alder Stefano AleMax Alessandro Senese Alexander Erlemann + Alexander Ryndin + Alexander Walter (SilvanuZ) Alexandre Beaudoin alex clavelle - Ali Al-Khalifa Allan Davis Allen Schade Ancient Phoenix Anders Marstein Kruke Andreas Krampitz - André Simões Andre Stackhouse andrew james morris Andrew Mansuetti - Andrew Rosenwinkel Andrew Thomas Ano Nim Anthony Avina @@ -330,16 +356,14 @@ generous deed immortalized in the next stable release of Godot Engine. AP Condomines Arch Toasty Arda Erol + Aria Armin Preiml Arseniy M - Arthur S. Muszynski Ashley Claymore Astier Mickael Aubrey Falconer AzulCrescent - B A Balázs Batári - Balázs Kondákor Bartosz Bielecki Bekhoucha Danyl Benedikt @@ -347,6 +371,7 @@ generous deed immortalized in the next stable release of Godot Engine. Bernd Jänichen Bjarne Voigtländer Black Block + blackjacksike Blair Allen Bobby CC Wong Borkzilla @@ -356,6 +381,7 @@ generous deed immortalized in the next stable release of Godot Engine. Brian Klein Brodie Fairhall Bronson Zgeb + Bùi Việt Thà nh Burney Waring Caleb Gartner Cameron Meyer @@ -364,7 +390,9 @@ generous deed immortalized in the next stable release of Godot Engine. Carwyn Edwards Cas Brugman Cassidy James + Cédric Givord Chad Steadman + Charles Alston Chris Chapin Chris Jagusch Chris Langford @@ -377,8 +405,9 @@ generous deed immortalized in the next stable release of Godot Engine. Christoph Woinke Chris Truebe Clay Heaton + Cody Parker Conall O - Cyrelouyea + Craig Post CzechBlueBear Daniel Cheney Daniel Johnson @@ -398,10 +427,10 @@ generous deed immortalized in the next stable release of Godot Engine. Dr.Raccoon Duobix Duodecimal + DurrDiss Eduardo Teixeira Edward Herbert Edward Swartz - Eelco F Hillenius Egon Elbre Elgenzay Elias Nykrem @@ -409,7 +438,6 @@ generous deed immortalized in the next stable release of Godot Engine. Eric Ellingson Eric Williams Erkki Seppälä - ET Garcia Evan Rose Fain Faisal Alkubaisi @@ -423,6 +451,7 @@ generous deed immortalized in the next stable release of Godot Engine. FuDiggity Gadzhi Kharkharov gamedev by Celio + Game Endeavor Gary Thomas George Marques Gerard Ruiz Torruella @@ -438,19 +467,16 @@ generous deed immortalized in the next stable release of Godot Engine. Hal A helija Heribert Hirth - Hoai Nam Tran + Hieu Thanh Hunter Jones - Hylpher Ian Williams Iiari - iKlem IndustrialRobot + Ivan Nikolaev iveks - Ivica Å imić Jackson Harmer Jacob Jaguar - Jaiden Gerig Jaime Ruiz-Borau Vizárraga Jake D Jake Huxell @@ -461,12 +487,13 @@ generous deed immortalized in the next stable release of Godot Engine. Jamiee H Jamie Massey JARKKO PARVIAINEN + Jasiek Vetulani Jason Uechi Jean-Baptiste LEPESME Jeff Hungerford Jennifer Graves Jesse Dubay - Joe Alden + Jhon Adams Joe Klemmer John Gabriel Jonas @@ -483,42 +510,41 @@ generous deed immortalized in the next stable release of Godot Engine. Jorge Javier Araya Navarro Jose C. Rubio Joseph Catrambone - Josh Mitchell Josh Taylor - Joshua Southerland + Josue David Juanfran Jueast Julian Murgia June Little - JungleRobba + Justin Hamilton Justin Oaksford Justin Spedding KaDokta Kalin - Karel NÄ›mec Kauzig Keedong Park Keinan Powers Keith Bradner Kenji Kawabata + Ken Minardo Kenneth Lee Kent Jofur + Ketafuki Kevin McPhillips Kiri Jolly - Kiyohiro Kawamura (kyorohiro) Kjetil Haugland + Konstantin Goncharov + Kridsada Thanabulpong Kristian Nygaard Jensen KsyTek Games - Kuan Cheang kycho Kyle Jacobs Kyle Szklenski Kyuppin Laurent CHEA Laurent Tréguier - Lee Meichin + Laxman Pradhan LEMMiNO - Lenny Leonardo Dimano Lin Chear Linus Lind Lundgren @@ -527,13 +553,13 @@ generous deed immortalized in the next stable release of Godot Engine. Luis Gaemperle Luis M LunaticInAHat - Lurkars Major Haul makoto asano Malcolm Marco Lardelli Mark Jad Mark Krenz + Mark Malone Markus Martin Markus Michael Egger Martin FIbik @@ -550,8 +576,10 @@ generous deed immortalized in the next stable release of Godot Engine. Maxwell Megasploot Melissa Mears + Merlyn Morgan-Graham mewin Michael + Michael Bruce-Lockhart Michael Haney MichaÅ‚ Skwarek Mikayla @@ -566,27 +594,27 @@ generous deed immortalized in the next stable release of Godot Engine. Nathaniel Natrim nee + neighty Neil Blakey-Milner Neil Wang Nerdforge Nerdyninja Nicholas - Nicholas Girga Nick Allen Nick Macholl Niclas Eriksen Nicolas Goll-Perrier - Nicolás Montaña + Nicolas Rosset Nicolas SAN AGUSTIN Nima Farid NZ + oceoh OKV Oleg Reva Oleksandr Kryvonos Olivier Omar Delarosa Oscar Domingo - Oscar Norlander Parinya Teerakasemsuk patricio lara briones Patrick Dully @@ -595,24 +623,27 @@ generous deed immortalized in the next stable release of Godot Engine. Paul Mason PaweÅ‚ Kowal PaweÅ‚ Åyczkowski - Pedro Assuncao + Peter Höglund Petrus Prinsloo Philip Cohoe + Phillip Zolla Piotr Góral + Pipo Point08 Preethi Vaidyanathan - Price Comstock pwab + pyacier + Rad Cat Rafa Laguna Raffaele Aramo + RAMupgrade Remi Rampin Rémi Verschelde Reneator - Richard Diss + Riccardo Marini Richard Ivánek Riley Robert Farr (Larington) - Robert Larnach Rob Ruana Roger Smith Roland RzÄ…sa @@ -623,19 +654,19 @@ generous deed immortalized in the next stable release of Godot Engine. Ryan Groom Sam Edson Samuele Zolfanelli - sayaks + scapegoat57 Scott D. Yelich Scott Longley - ScottMakesGames + Sean Lynch Sebastian Michailidis Sebastian Vetter SeongWan Kim Sergiy Onenko - Shaher Shane Shane Sicienski Shane Spoor Siim Raidma + simdee Simon Jonas Larsen Simon Schoenenberger Simon Wenner @@ -644,20 +675,20 @@ generous deed immortalized in the next stable release of Godot Engine. smo1704 soft circles Squirrel - Stefano Caronia Steve Cloete + summerblind Sung soo Choi Svenne Krap tadashi endo tannhauser_gate + Tarch Terry Theodore Lindsey - TheTrainDoctor TheVoiceInMyHead thomas Thomas Bechtold Thomas Detoy - Thomas Kelly + Thomas Horwath Tim Drumheller Tim Erskine Tim Gleason @@ -671,7 +702,6 @@ generous deed immortalized in the next stable release of Godot Engine. Travis O'Brien Trent Skinner tril zerobyte - Triptych Triumph263 . Troy Bonneau Tryggve Sollid @@ -684,8 +714,6 @@ generous deed immortalized in the next stable release of Godot Engine. Victor Vigilant Watch Viktor Ismagilov - Vitaliy Sapronenko - Vitor Balbio Vladimir Savin Vladislav Smirnov Výrus Hemomancer @@ -693,17 +721,15 @@ generous deed immortalized in the next stable release of Godot Engine. Wayne Haak werner mendizabal Wiley Thompson - Will William Edwards William F Siqueira William Hogben Wyatt Goodin + Xaver Fischer xenomat Yegor Smirnov - YiYin Gu Zack Yang Zak Stephens - ΒΑΣΙΛΗΣ ΓΕΩΡΓΑΚΟΠΟΥΛΟΣ è•æƒŸå… éƒæ™¨ç…œ diff --git a/SConstruct b/SConstruct index 2281b8a77f..000c918808 100644 --- a/SConstruct +++ b/SConstruct @@ -105,15 +105,14 @@ if profile: opts = Variables(customs, ARGUMENTS) # Target build options -opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "") -opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64"))) opts.Add("p", "Platform (alias for 'platform')", "") opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "") +opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True)) opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release"))) +opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "") +opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64"))) opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size"))) - -opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True)) -opts.Add(BoolVariable("tests", "Build the unit tests", False)) +opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) opts.Add(BoolVariable("use_lto", "Use link-time optimization", False)) # Components @@ -121,13 +120,15 @@ opts.Add(BoolVariable("deprecated", "Enable deprecated features", True)) opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True)) opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") +opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) # Advanced options -opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) +opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False)) opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True)) +opts.Add(BoolVariable("tests", "Build the unit tests", False)) +opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no"))) opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False)) -opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False)) opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "") opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False)) opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) @@ -237,8 +238,14 @@ if env_base["custom_modules"]: Exit(255) for path in module_search_paths: + if path == "modules": + # Built-in modules don't have nested modules, + # so save the time it takes to parse directories. + modules = methods.detect_modules(path, recursive=False) + else: # External. + modules = methods.detect_modules(path, env_base["custom_modules_recursive"]) # Note: custom modules can override built-in ones. - modules_detected.update(methods.detect_modules(path)) + modules_detected.update(modules) include_path = os.path.dirname(path) if include_path: env_base.Prepend(CPPPATH=[include_path]) @@ -308,7 +315,7 @@ if selected_platform in platform_list: else: env = env_base.Clone() - # Compilation DB requires SCons 3.1.1+. + # Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later. from SCons import __version__ as scons_raw_version scons_ver = env._get_major_minor_revision(scons_raw_version) @@ -317,12 +324,34 @@ if selected_platform in platform_list: env.Tool("compilation_db") env.Alias("compiledb", env.CompilationDatabase()) + # 'dev' and 'production' are aliases to set default options if they haven't been set + # manually by the user. We use `ARGUMENTS.get()` to check if they were manually set. if env["dev"]: - env["verbose"] = True - env["warnings"] = "extra" - env["werror"] = True + env["verbose"] = ARGUMENTS.get("verbose", True) + env["warnings"] = ARGUMENTS.get("warnings", "extra") + env["werror"] = ARGUMENTS.get("werror", True) if env["tools"]: - env["tests"] = True + env["tests"] = ARGUMENTS.get("tests", True) + if env["production"]: + env["use_static_cpp"] = ARGUMENTS.get("use_static_cpp", True) + env["use_lto"] = ARGUMENTS.get("use_lto", True) + env["debug_symbols"] = ARGUMENTS.get("debug_symbols", False) + if not env["tools"] and env["target"] == "debug": + print( + "WARNING: Requested `production` build with `tools=no target=debug`, " + "this will give you a full debug template (use `target=release_debug` " + "for an optimized template with debug features)." + ) + if env.msvc: + print( + "WARNING: For `production` Windows builds, you should use MinGW with GCC " + "or Clang instead of Visual Studio, as they can better optimize the " + "GDScript VM in a very significant way. MSVC LTO also doesn't work " + "reliably for our use case." + "If you want to use MSVC nevertheless for production builds, set " + "`debug_symbols=no use_lto=no` instead of the `production=yes` option." + ) + Exit(255) env.extra_suffix = "" diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 70e8133eaa..b4ca31d77a 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -597,6 +597,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) { // If we're loading a project.godot from source code, we can operate some // ProjectSettings conversions if need be. _convert_to_last_version(config_version); + last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); return OK; } else if (err != OK) { ERR_PRINT("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted."); @@ -676,7 +677,11 @@ void ProjectSettings::clear(const String &p_name) { } Error ProjectSettings::save() { - return save_custom(get_resource_path().plus_file("project.godot")); + Error error = save_custom(get_resource_path().plus_file("project.godot")); + if (error == OK) { + last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); + } + return error; } Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) { @@ -1239,8 +1244,8 @@ ProjectSettings::ProjectSettings() { custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor"); custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); - custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); - custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects"); + GLOBAL_DEF("physics/2d/run_on_thread", false); + GLOBAL_DEF("physics/3d/run_on_thread", false); GLOBAL_DEF("debug/settings/profiler/max_functions", 16384); custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1"); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 59c56c23c2..645506f302 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -78,6 +78,8 @@ protected: int last_order = NO_BUILTIN_ORDER_BASE; int last_builtin_order = 0; + uint64_t last_save_time = 0; + Map<StringName, VariantContainer> props; String resource_path; Map<StringName, PropertyInfo> custom_prop_info; @@ -113,7 +115,6 @@ protected: Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false); -protected: static void _bind_methods(); public: @@ -150,6 +151,7 @@ public: Error save(); void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info); const Map<StringName, PropertyInfo> &get_custom_property_info() const; + uint64_t get_last_saved_time() { return last_save_time; } Vector<String> get_optimizer_presets() const; diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 456a97e5e5..f568ee754d 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -86,9 +86,9 @@ RES _ResourceLoader::load_threaded_get(const String &p_path) { return res; } -RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache) { +RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) { Error err = OK; - RES ret = ResourceLoader::load(p_path, p_type_hint, p_no_cache, &err); + RES ret = ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'."); return ret; @@ -135,7 +135,7 @@ void _ResourceLoader::_bind_methods() { ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get); - ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE)); ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type); ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources); ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies); @@ -146,6 +146,10 @@ void _ResourceLoader::_bind_methods() { BIND_ENUM_CONSTANT(THREAD_LOAD_IN_PROGRESS); BIND_ENUM_CONSTANT(THREAD_LOAD_FAILED); BIND_ENUM_CONSTANT(THREAD_LOAD_LOADED); + + BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE); + BIND_ENUM_CONSTANT(CACHE_MODE_REUSE); + BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE); } ////// _ResourceSaver ////// diff --git a/core/core_bind.h b/core/core_bind.h index 3305c93089..44e620085a 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -56,13 +56,19 @@ public: THREAD_LOAD_LOADED }; + enum CacheMode { + CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource. + CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available + CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk + }; + static _ResourceLoader *get_singleton() { return singleton; } Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false); ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array()); RES load_threaded_get(const String &p_path); - RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false); + RES load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE); Vector<String> get_recognized_extensions_for_type(const String &p_type); void set_abort_on_missing_resources(bool p_abort); PackedStringArray get_dependencies(const String &p_path); @@ -73,6 +79,7 @@ public: }; VARIANT_ENUM_CAST(_ResourceLoader::ThreadLoadStatus); +VARIANT_ENUM_CAST(_ResourceLoader::CacheMode); class _ResourceSaver : public Object { GDCLASS(_ResourceSaver, Object); diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 3df121b9cb..ef5dbf17bb 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -426,6 +426,12 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MISC1); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE1); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE2); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE3); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE4); + BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_TOUCHPAD); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_SDL_MAX); BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MAX); diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp index 18ac2a2d43..ff8569e45d 100644 --- a/core/core_string_names.cpp +++ b/core/core_string_names.cpp @@ -76,5 +76,6 @@ CoreStringNames::CoreStringNames() : bind(StaticCString::create("bind")), unbind(StaticCString::create("unbind")), emit(StaticCString::create("emit")), - notification(StaticCString::create("notification")) { + notification(StaticCString::create("notification")), + property_list_changed(StaticCString::create("property_list_changed")) { } diff --git a/core/core_string_names.h b/core/core_string_names.h index b4e386f3bc..abe751372e 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -96,6 +96,7 @@ public: StringName unbind; StringName emit; StringName notification; + StringName property_list_changed; }; #endif // CORE_STRING_NAMES_H diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index 99f4fb232d..f43f3e3290 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -141,7 +141,7 @@ void Crypto::_bind_methods() { /// Resource loader/saver -RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { String el = p_path.get_extension().to_lower(); if (el == "crt") { X509Certificate *cert = X509Certificate::create(); diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 30d2129e3d..9438fcfea5 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -116,7 +116,7 @@ public: class ResourceFormatLoaderCrypto : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt index 180708cea6..668a531b1f 100644 --- a/core/input/gamecontrollerdb.txt +++ b/core/input/gamecontrollerdb.txt @@ -1,4 +1,4 @@ -# Game Controller DB for SDL in 2.0.10 format +# Game Controller DB for SDL in 2.0.9 format # Source: https://github.com/gabomdq/SDL_GameControllerDB # Windows @@ -35,7 +35,7 @@ 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, -03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, @@ -80,14 +80,15 @@ 030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows, 03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows, +030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows, 030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, -030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, -030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -98,6 +99,7 @@ 03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows, 03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows, +03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, @@ -119,6 +121,7 @@ 030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows, 03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -164,7 +167,8 @@ 030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, -030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,lefttrigger:b6,righttrigger:b7,platform:Windows, +030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows, 03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -193,6 +197,8 @@ 03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -234,6 +240,7 @@ 030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, 03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, 03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, @@ -244,7 +251,6 @@ 03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, -03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b13,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4, 03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -259,6 +265,7 @@ 030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, +03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows, 0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, 0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, 030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, @@ -271,8 +278,8 @@ 03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, -03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b0,y:b1,platform:Windows, -03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows, +03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows, +03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows, 03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, @@ -283,6 +290,8 @@ 03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows, 0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, +03000000a30c00002500000000000000,Sega Genesis Mini 3B controller,a:b2,b:b1,start:b9,dpup:-a4,dpdown:+a4,dpleft:-a3,dpright:+a3,righttrigger:b5,platform:Windows, +03000000a30c00002400000000000000,Sega Mega Drive Mini 6B controller,a:b2,b:b1,start:b9,dpup:-a4,dpdown:+a4,dpleft:-a3,dpright:+a3,rightshoulder:b4,righttrigger:b5,x:b3,y:b0,platform:Windows, 030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -328,6 +337,8 @@ 030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:+a3,righty:+a4,start:b4,x:b2,y:b3,platform:Windows, 030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000005e040000ff02000000007801,Xbox One Elite Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, @@ -338,7 +349,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, # Mac OS X -030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X, @@ -355,12 +366,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, -03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X, +03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X, @@ -427,6 +440,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -446,6 +460,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, 030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X, +030000004c050000e60c000000010000,Sony DualSense,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X, @@ -474,6 +489,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, 030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, 030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, @@ -506,12 +523,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, -03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, -05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, -030000005e0400008e02000020010000,8BitDo Wireless Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -03000000c82d00000031000011010000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +030000005e0400008e02000020010000,8BitDo Wireless Adapter (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000031000011010000,8BitDo Wireless Adapter (DInput),a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +050000005e040000e002000030110000,8BitDo Zero 2 (XInput),a:b0,b:b1,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,start:b7,x:b2,y:b3,platform:Linux, 05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, 05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, @@ -521,11 +539,16 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux, -05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, 03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -567,6 +590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -592,6 +616,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000242f00002d00000011010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, 030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, @@ -600,10 +625,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, -030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,platform:Linux, +030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, 030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +050000004d4f435554452d3035305800,M54-PC,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,platform:Linux, 05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -635,6 +660,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, 05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, @@ -642,12 +669,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux, -060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, +03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b0,y:b3,platform:Linux, 050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, @@ -666,21 +695,23 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux, 03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +05000000491900000204000000000000,PG-9118,x:b76,a:b73,b:b74,y:b77,back:b83,start:b84,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b79,lefttrigger:b81,rightshoulder:b80,righttrigger:b82,leftstick:b86,rightstick:b87,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux, 0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, +03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, @@ -709,6 +740,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, 030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, @@ -717,6 +750,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -735,14 +769,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, +03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux, 03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, 03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, 03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, 03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, -03000000a30600001005000000010000,Saitek Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, 03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, 03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, 03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -754,15 +789,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, 03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, -05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -774,11 +809,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, 03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00001431000010010000,SZMY-POWER CO. LTD. PS3 gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, 030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux, +030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux, 030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, 030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -815,6 +852,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -823,6 +864,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0, # Android 05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android, @@ -857,20 +899,27 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android, +32633532643734376632656664383733,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, +61303162353165316365336436343139,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, 050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android, 30306539356238653637313730656134,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android, +050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,platform:Android, 050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android, 34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android, 050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android, @@ -879,13 +928,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, 05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, 05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS, +05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, 05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, -050000004c050000cc090000df070000,DUALSHOCK 4 Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, 4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, +050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000004c050000cc090000ff876d01,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,,platform:iOS, +050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS, 05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, +050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt index e8e250e3be..c43cd6c8ac 100644 --- a/core/input/godotcontrollerdb.txt +++ b/core/input/godotcontrollerdb.txt @@ -22,6 +22,12 @@ MacOSX045e028e,Xbox 360 Wired Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b MacOSX045e02d1,Xbox One Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript MacOSX045e02ea,Xbox One S Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript MacOSX045e0b12,Xbox Series X Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript +Linux15320a14,Razer Wolverine Ultimate,a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript +Linux05832060,iBuffalo BSGP801,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +MacOSX05832060,iBuffalo BSGP801,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +Linux0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +Windows0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript +MacOSX0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a4,dpleft:-a3,dpdown:+a4,dpright:+a3,platform:Javascript # UWP __UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:UWP, diff --git a/core/input/input.cpp b/core/input/input.cpp index 2e3f112ebc..047aeb47fd 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -55,6 +55,12 @@ static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = { "dpdown", "dpleft", "dpright", + "misc1", + "paddle1", + "paddle2", + "paddle3", + "paddle4", + "touchpad", }; static const char *_joy_axes[JOY_AXIS_SDL_MAX] = { diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 2771a15b80..c91dc4d067 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -985,6 +985,12 @@ static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = { TTRC("D-pad Down"), TTRC("D-pad Left"), TTRC("D-pad Right"), + TTRC("Xbox Share, PS5 Microphone, Nintendo Capture"), + TTRC("Xbox Paddle 1"), + TTRC("Xbox Paddle 2"), + TTRC("Xbox Paddle 3"), + TTRC("Xbox Paddle 4"), + TTRC("PS4/5 Touchpad"), }; String InputEventJoypadButton::as_text() const { diff --git a/core/input/input_event.h b/core/input/input_event.h index 1500faa24c..a354119cf9 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -76,7 +76,13 @@ enum JoyButtonList { JOY_BUTTON_DPAD_DOWN = 12, JOY_BUTTON_DPAD_LEFT = 13, JOY_BUTTON_DPAD_RIGHT = 14, - JOY_BUTTON_SDL_MAX = 15, + JOY_BUTTON_MISC1 = 15, + JOY_BUTTON_PADDLE1 = 16, + JOY_BUTTON_PADDLE2 = 17, + JOY_BUTTON_PADDLE3 = 18, + JOY_BUTTON_PADDLE4 = 19, + JOY_BUTTON_TOUCHPAD = 20, + JOY_BUTTON_SDL_MAX = 21, JOY_BUTTON_MAX = 36, // Android supports up to 36 buttons. }; diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 8ca1cb3beb..7de038e6fe 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -122,7 +122,7 @@ void ImageLoader::cleanup() { ///////////////// -RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index bf67e1486f..a5d588e0b5 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -72,7 +72,7 @@ public: class ResourceFormatLoaderImage : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/logger.cpp b/core/io/logger.cpp index da200f5717..bd0285a7a9 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -207,7 +207,7 @@ void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) { Memory::free_static(buf); } - if (p_err || GLOBAL_GET("application/run/flush_stdout_on_print")) { + if (p_err || !ProjectSettings::get_singleton() || GLOBAL_GET("application/run/flush_stdout_on_print")) { // Don't always flush when printing stdout to avoid performance // issues when `print()` is spammed in release builds. file->flush(); @@ -228,7 +228,7 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) { vfprintf(stderr, p_format, p_list); } else { vprintf(p_format, p_list); - if (GLOBAL_GET("application/run/flush_stdout_on_print")) { + if (!ProjectSettings::get_singleton() || GLOBAL_GET("application/run/flush_stdout_on_print")) { // Don't always flush when printing stdout to avoid performance // issues when `print()` is spammed in release builds. fflush(stdout); diff --git a/core/io/resource.cpp b/core/io/resource.cpp index db79998a90..8560e2abc7 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -87,7 +87,6 @@ void Resource::set_path(const String &p_path, bool p_take_over) { ResourceCache::lock.write_unlock(); } - _change_notify("resource_path"); _resource_path_changed(); } @@ -105,7 +104,6 @@ int Resource::get_subindex() const { void Resource::set_name(const String &p_name) { name = p_name; - _change_notify("resource_name"); } String Resource::get_name() const { @@ -116,20 +114,18 @@ bool Resource::editor_can_reload_from_file() { return true; //by default yes } -void Resource::reload_from_file() { - String path = get_path(); - if (!path.is_resource_file()) { - return; +void Resource::reset_state() { +} +Error Resource::copy_from(const Ref<Resource> &p_resource) { + ERR_FAIL_COND_V(p_resource.is_null(), ERR_INVALID_PARAMETER); + if (get_class() != p_resource->get_class()) { + return ERR_INVALID_PARAMETER; } - Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true); - - if (!s.is_valid()) { - return; - } + reset_state(); //may want to reset state List<PropertyInfo> pi; - s->get_property_list(&pi); + p_resource->get_property_list(&pi); for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { @@ -139,8 +135,23 @@ void Resource::reload_from_file() { continue; //do not change path } - set(E->get().name, s->get(E->get().name)); + set(E->get().name, p_resource->get(E->get().name)); } + return OK; +} +void Resource::reload_from_file() { + String path = get_path(); + if (!path.is_resource_file()) { + return; + } + + Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + + if (!s.is_valid()) { + return; + } + + copy_from(s); } Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) { diff --git a/core/io/resource.h b/core/io/resource.h index d0cd6ea3ac..ae18ac0c8a 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -90,6 +90,8 @@ public: static Node *(*_get_local_scene_func)(); //used by editor virtual bool editor_can_reload_from_file(); + virtual void reset_state(); //for resources that use variable amount of properties, either via _validate_property or _get_property_list, this function needs to be implemented to correctly clear state + virtual Error copy_from(const Ref<Resource> &p_resource); virtual void reload_from_file(); void register_owner(Object *p_owner); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index fad58d65fd..fb6ad7d65e 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -313,17 +313,12 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { uint32_t index = f->get_32(); String path = res_path + "::" + itos(index); - if (use_nocache) { - if (!internal_index_cache.has(path)) { - WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data()); - } - r_v = internal_index_cache[path]; + //always use internal cache for loading internal resources + if (!internal_index_cache.has(path)) { + WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data()); + r_v = Variant(); } else { - RES res = ResourceLoader::load(path); - if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); - } - r_v = res; + r_v = internal_index_cache[path]; } } break; @@ -645,7 +640,7 @@ Error ResourceLoaderBinary::load() { } } else { - Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, local_path); + Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, ResourceFormatLoader::CACHE_MODE_REUSE, local_path); if (err != OK) { if (!ResourceLoader::get_abort_on_missing_resources()) { ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type); @@ -675,7 +670,7 @@ Error ResourceLoaderBinary::load() { path = res_path + "::" + path; } - if (!use_nocache) { + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE) { if (ResourceCache::has(path)) { //already loaded, don't do anything stage++; @@ -684,7 +679,7 @@ Error ResourceLoaderBinary::load() { } } } else { - if (!use_nocache && !ResourceCache::has(res_path)) { + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && !ResourceCache::has(res_path)) { path = res_path; } } @@ -695,26 +690,40 @@ Error ResourceLoaderBinary::load() { String t = get_unicode_string(); - Object *obj = ClassDB::instance(t); - if (!obj) { - error = ERR_FILE_CORRUPT; - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + "."); - } + RES res; - Resource *r = Object::cast_to<Resource>(obj); - if (!r) { - String obj_class = obj->get_class(); - error = ERR_FILE_CORRUPT; - memdelete(obj); //bye - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + "."); + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) { + //use the existing one + Resource *r = ResourceCache::get(path); + if (r->get_class() == t) { + r->reset_state(); + res = Ref<Resource>(r); + } } - RES res = RES(r); + if (res.is_null()) { + //did not replace - if (path != String()) { - r->set_path(path); + Object *obj = ClassDB::instance(t); + if (!obj) { + error = ERR_FILE_CORRUPT; + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + "."); + } + + Resource *r = Object::cast_to<Resource>(obj); + if (!r) { + String obj_class = obj->get_class(); + error = ERR_FILE_CORRUPT; + memdelete(obj); //bye + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + "."); + } + + res = RES(r); + if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it + } + r->set_subindex(subindex); } - r->set_subindex(subindex); if (!main) { internal_index_cache[path] = res; @@ -961,7 +970,7 @@ ResourceLoaderBinary::~ResourceLoaderBinary() { } } -RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -972,7 +981,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); ResourceLoaderBinary loader; - loader.use_nocache = p_no_cache; + loader.cache_mode = p_cache_mode; loader.use_sub_threads = p_use_sub_threads; loader.progress = r_progress; String path = p_original_path != "" ? p_original_path : p_path; diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 428725f1d2..3592bbdbc4 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -78,7 +78,7 @@ class ResourceLoaderBinary { Map<String, String> remaps; Error error = OK; - bool use_nocache = false; + ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; friend class ResourceFormatLoaderBinary; @@ -103,7 +103,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index d86877ee14..3e460726f6 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -116,7 +116,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy return OK; } -RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -128,7 +128,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ return RES(); } - RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress); + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress); #ifdef TOOLS_ENABLED if (res.is_valid()) { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index d31273e3cb..bda8b74b73 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -57,7 +57,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { public: static ResourceFormatImporter *get_singleton() { return singleton; } - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index d66511a39f..588af0f0ae 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -113,9 +113,9 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) } } -RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (get_script_instance() && get_script_instance()->has_method("load")) { - Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads); + Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads, p_cache_mode); if (res.get_type() == Variant::INT) { if (r_error) { @@ -164,7 +164,7 @@ Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map< void ResourceFormatLoader::_bind_methods() { { - MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path")); + MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"), PropertyInfo(Variant::BOOL, "use_sub_threads"), PropertyInfo(Variant::INT, "cache_mode")); info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; ClassDB::add_virtual_method(get_class_static(), info); } @@ -178,7 +178,7 @@ void ResourceFormatLoader::_bind_methods() { /////////////////////////////////// -RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) { bool found = false; // Try all loaders and pick the first match for the type hint @@ -187,7 +187,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c continue; } found = true; - RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache); + RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode); if (res.is_null()) { continue; } @@ -214,7 +214,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { //this is an actual thread, so wait for Ok fom semaphore thread_load_semaphore->wait(); //wait until its ok to start loading } - load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, false, &load_task.error, load_task.use_sub_threads, &load_task.progress); + load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, load_task.cache_mode, &load_task.error, load_task.use_sub_threads, &load_task.progress); load_task.progress = 1.0; //it was fully loaded at this point, so force progress to 1.0 @@ -267,7 +267,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { thread_load_mutex->unlock(); } -Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) { +Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) { String local_path; if (p_path.is_rel_path()) { local_path = "res://" + p_path; @@ -314,6 +314,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped); load_task.local_path = local_path; load_task.type_hint = p_type_hint; + load_task.cache_mode = p_cache_mode; load_task.use_sub_threads = p_use_sub_threads; { //must check if resource is already loaded before attempting to load it in a thread @@ -501,7 +502,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { return resource; } -RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { +RES ResourceLoader::load(const String &p_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -513,7 +514,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p local_path = ProjectSettings::get_singleton()->localize_path(p_path); } - if (!p_no_cache) { + if (p_cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE) { thread_load_mutex->lock(); //Is it already being loaded? poll until done @@ -561,6 +562,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p load_task.local_path = local_path; load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped); load_task.type_hint = p_type_hint; + load_task.cache_mode = p_cache_mode; //ignore load_task.loader_id = Thread::get_caller_id(); thread_load_tasks[local_path] = load_task; @@ -581,7 +583,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p print_verbose("Loading resource: " + path); float p; - RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error, false, &p); + RES res = _load(path, local_path, p_type_hint, p_cache_mode, r_error, false, &p); if (res.is_null()) { print_verbose("Failed loading resource: " + path); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index dbf6be46c5..38a756c52f 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -38,11 +38,18 @@ class ResourceFormatLoader : public Reference { GDCLASS(ResourceFormatLoader, Reference); +public: + enum CacheMode { + CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource. + CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available + CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk + }; + protected: static void _bind_methods(); public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual bool exists(const String &p_path) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; @@ -99,7 +106,7 @@ private: friend class ResourceFormatImporter; friend class ResourceInteractiveLoader; //internal load function - static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress); + static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress); static ResourceLoadedCallback _loaded_callback; @@ -114,6 +121,7 @@ private: String type_hint; float progress = 0.0; ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS; + ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; Error error = OK; RES resource; bool xl_remapped = false; @@ -136,11 +144,11 @@ private: static float _dependency_get_progress(const String &p_path); public: - static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, const String &p_source_resource = String()); + static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, const String &p_source_resource = String()); static ThreadLoadStatus load_threaded_get_status(const String &p_path, float *r_progress = nullptr); static RES load_threaded_get(const String &p_path, Error *r_error = nullptr); - static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = nullptr); + static RES load(const String &p_path, const String &p_type_hint = "", ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, Error *r_error = nullptr); static bool exists(const String &p_path, const String &p_type_hint = ""); static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions); diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index ce2c3eb1cd..0e11ff514a 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -277,7 +277,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { return translation; } -RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index a524972588..36d33fcac3 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -38,7 +38,7 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: static RES load_translation(FileAccess *f, Error *r_error = nullptr); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h index 5773da9211..a5616b8d79 100644 --- a/core/math/audio_frame.h +++ b/core/math/audio_frame.h @@ -47,6 +47,9 @@ static inline float undenormalise(volatile float f) { return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f; } +static const float AUDIO_PEAK_OFFSET = 0.0000000001f; +static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear2db(AUDIO_PEAK_OFFSET) + struct AudioFrame { //left and right samples float l, r; diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 7dbda1d149..1066cf5e30 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -89,7 +89,7 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ } real_t sine, cotangent, deltaZ; - real_t radians = p_fovy_degrees / 2.0 * Math_PI / 180.0; + real_t radians = Math::deg2rad(p_fovy_degrees / 2.0); deltaZ = p_z_far - p_z_near; sine = Math::sin(radians); @@ -116,7 +116,7 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ real_t left, right, modeltranslation, ymax, xmax, frustumshift; - ymax = p_z_near * tan(p_fovy_degrees * Math_PI / 360.0f); + ymax = p_z_near * tan(Math::deg2rad(p_fovy_degrees / 2.0)); xmax = ymax * p_aspect; frustumshift = (p_intraocular_dist / 2.0) * p_z_near / p_convergence_dist; diff --git a/core/math/color.cpp b/core/math/color.cpp index 0398d43838..e1b45cac9c 100644 --- a/core/math/color.cpp +++ b/core/math/color.cpp @@ -408,6 +408,8 @@ Color Color::get_named_color(int p_idx) { return named_colors[p_idx].color; } +// For a version that errors on invalid values instead of returning +// a default color, use the Color(String) constructor instead. Color Color::from_string(const String &p_string, const Color &p_default) { if (html_is_valid(p_string)) { return html(p_string); diff --git a/core/math/color.h b/core/math/color.h index d3b27a9c65..5eb8b1119a 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -241,6 +241,19 @@ struct Color { b = p_c.b; a = p_a; } + + Color(const String &p_code) { + if (html_is_valid(p_code)) { + *this = html(p_code); + } else { + *this = named(p_code); + } + } + + Color(const String &p_code, float p_a) { + *this = Color(p_code); + a = p_a; + } }; bool Color::operator<(const Color &p_color) const { diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index 553184303d..a4a7463bfd 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -777,10 +777,11 @@ Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) { Vector<Plane> planes; + const double sides_step = Math_TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; - normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides); - normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides); + normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); + normal[(p_axis + 2) % 3] = Math::sin(i * sides_step); planes.push_back(Plane(normal, p_radius)); } @@ -805,10 +806,11 @@ Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; + const double lon_step = Math_TAU / p_lons; for (int i = 0; i < p_lons; i++) { Vector3 normal; - normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_lons); - normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_lons); + normal[(p_axis + 1) % 3] = Math::cos(i * lon_step); + normal[(p_axis + 2) % 3] = Math::sin(i * lon_step); planes.push_back(Plane(normal, p_radius)); @@ -835,10 +837,11 @@ Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; + const double sides_step = Math_TAU / p_sides; for (int i = 0; i < p_sides; i++) { Vector3 normal; - normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides); - normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides); + normal[(p_axis + 1) % 3] = Math::cos(i * sides_step); + normal[(p_axis + 2) % 3] = Math::sin(i * sides_step); planes.push_back(Plane(normal, p_radius)); diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 825817af5e..4ef9b4dbe6 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -252,27 +252,34 @@ public: return true; } - static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) { + static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr, int p_cylinder_axis = 2) { Vector3 rel = (p_to - p_from); real_t rel_l = rel.length(); if (rel_l < CMP_EPSILON) { return false; // Both points are the same. } + ERR_FAIL_COND_V(p_cylinder_axis < 0, false); + ERR_FAIL_COND_V(p_cylinder_axis > 2, false); + Vector3 cylinder_axis; + cylinder_axis[p_cylinder_axis] = 1.0; + // First check if they are parallel. Vector3 normal = (rel / rel_l); - Vector3 crs = normal.cross(Vector3(0, 0, 1)); + Vector3 crs = normal.cross(cylinder_axis); real_t crs_l = crs.length(); - Vector3 z_dir; + Vector3 axis_dir; if (crs_l < CMP_EPSILON) { - z_dir = Vector3(1, 0, 0); // Any x/y vector OK. + Vector3 side_axis; + side_axis[(p_cylinder_axis + 1) % 3] = 1.0; // Any side axis OK. + axis_dir = side_axis; } else { - z_dir = crs / crs_l; + axis_dir = crs / crs_l; } - real_t dist = z_dir.dot(p_from); + real_t dist = axis_dir.dot(p_from); if (dist >= p_radius) { return false; // Too far away. @@ -285,10 +292,10 @@ public: } Size2 size(Math::sqrt(w2), p_height * 0.5); - Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized(); + Vector3 side_dir = axis_dir.cross(cylinder_axis).normalized(); - Vector2 from2D(x_dir.dot(p_from), p_from.z); - Vector2 to2D(x_dir.dot(p_to), p_to.z); + Vector2 from2D(side_dir.dot(p_from), p_from[p_cylinder_axis]); + Vector2 to2D(side_dir.dot(p_to), p_to[p_cylinder_axis]); real_t min = 0, max = 1; @@ -335,10 +342,12 @@ public: Vector3 res_normal = result; if (axis == 0) { - res_normal.z = 0; + res_normal[p_cylinder_axis] = 0; } else { - res_normal.x = 0; - res_normal.y = 0; + int axis_side = (p_cylinder_axis + 1) % 3; + res_normal[axis_side] = 0; + axis_side = (axis_side + 1) % 3; + res_normal[axis_side] = 0; } res_normal.normalize(); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index c7d24e9c58..267f6a4fe2 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -223,11 +223,11 @@ public: return value; } - static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * Math_PI / 180.0; } - static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * Math_PI / 180.0; } + static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * (Math_PI / 180.0); } + static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * (Math_PI / 180.0); } - static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y * 180.0 / Math_PI; } - static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y * 180.0 / Math_PI; } + static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y * (180.0 / Math_PI); } + static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y * (180.0 / Math_PI); } static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; } static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; } diff --git a/core/object/object.cpp b/core/object/object.cpp index 171bc4dc2c..8f2eed3200 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -808,21 +808,6 @@ String Object::to_string() { return "[" + get_class() + ":" + itos(get_instance_id()) + "]"; } -void Object::_changed_callback(Object *p_changed, const char *p_prop) { -} - -void Object::add_change_receptor(Object *p_receptor) { - change_receptors.insert(p_receptor); -} - -void Object::remove_change_receptor(Object *p_receptor) { - change_receptors.erase(p_receptor); -} - -void Object::property_list_changed_notify() { - _change_notify(); -} - void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) { //this function is not meant to be used in any of these ways ERR_FAIL_COND(p_script.is_null()); @@ -856,7 +841,7 @@ void Object::set_script(const Variant &p_script) { } } - _change_notify(); //scripts may add variables, so refresh is desired + notify_property_list_changed(); //scripts may add variables, so refresh is desired emit_signal(CoreStringNames::get_singleton()->script_changed); } @@ -1496,6 +1481,10 @@ void Object::clear_internal_resource_paths() { } } +void Object::notify_property_list_changed() { + emit_signal(CoreStringNames::get_singleton()->property_list_changed); +} + void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_class"), &Object::get_class); ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class); @@ -1562,7 +1551,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals); ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals); - ClassDB::bind_method(D_METHOD("property_list_changed_notify"), &Object::property_list_changed_notify); + ClassDB::bind_method(D_METHOD("notify_property_list_changed"), &Object::notify_property_list_changed); ClassDB::bind_method(D_METHOD("set_message_translation", "enable"), &Object::set_message_translation); ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages); @@ -1574,6 +1563,7 @@ void Object::_bind_methods() { ClassDB::add_virtual_method("Object", MethodInfo("free"), false); ADD_SIGNAL(MethodInfo("script_changed")); + ADD_SIGNAL(MethodInfo("property_list_changed")); BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what"))); BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value"))); diff --git a/core/object/object.h b/core/object/object.h index 7e460462cf..b695ce9bc3 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -454,7 +454,6 @@ private: #endif bool _block_signals = false; int _predelete_ok = 0; - Set<Object *> change_receptors; ObjectID _instance_id; bool _predelete(); void _postinitialize(); @@ -523,9 +522,6 @@ protected: static void get_valid_parents_static(List<String> *p_parents); static void _get_valid_parents_static(List<String> *p_parents); - void property_list_changed_notify(); - virtual void _changed_callback(Object *p_changed, const char *p_prop); - //Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant()); //void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant()); @@ -555,16 +551,8 @@ public: //should be protected, but bug in clang++ _FORCE_INLINE_ static void register_custom_data_to_otdb() {} public: -#ifdef TOOLS_ENABLED - _FORCE_INLINE_ void _change_notify(const char *p_property = "") { - _edited = true; - for (Set<Object *>::Element *E = change_receptors.front(); E; E = E->next()) { - ((Object *)(E->get()))->_changed_callback(this, p_property); - } - } -#else - _FORCE_INLINE_ void _change_notify(const char *p_what = "") {} -#endif + void notify_property_list_changed(); + static void *get_class_ptr_static() { static int ptr; return &ptr; @@ -574,10 +562,6 @@ public: _FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; } - // this is used for editors - void add_change_receptor(Object *p_receptor); - void remove_change_receptor(Object *p_receptor); - template <class T> static T *cast_to(Object *p_object) { #ifndef NO_SAFE_CAST diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index c3f109a147..d0636e8b84 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -515,7 +515,7 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c } if (owner && owner->get_script_instance() == this) { - owner->_change_notify(); + owner->notify_property_list_changed(); } //change notify diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 0b6311dadf..59fda65d43 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3072,39 +3072,46 @@ int String::rfindn(const String &p_str, int p_from) const { bool String::ends_with(const String &p_string) const { int l = p_string.length(); + if (l > length()) { + return false; + } + if (l == 0) { return true; } - int pos = rfind(p_string); - if (pos == -1) { - return false; + const char32_t *p = &p_string[0]; + const char32_t *s = &operator[](length() - l); + + for (int i = 0; i < l; i++) { + if (p[i] != s[i]) { + return false; + } } - return pos + l == length(); + + return true; } bool String::begins_with(const String &p_string) const { - if (p_string.length() > length()) { + int l = p_string.length(); + if (l > length()) { return false; } - int l = p_string.length(); if (l == 0) { return true; } - const char32_t *src = &p_string[0]; - const char32_t *str = &operator[](0); + const char32_t *p = &p_string[0]; + const char32_t *s = &operator[](0); - int i = 0; - for (; i < l; i++) { - if (src[i] != str[i]) { + for (int i = 0; i < l; i++) { + if (p[i] != s[i]) { return false; } } - // only if i == l the p_string matches the beginning - return i == l; + return true; } bool String::begins_with(const char *p_string) const { diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h index 7861c76153..0012cea72d 100644 --- a/core/templates/command_queue_mt.h +++ b/core/templates/command_queue_mt.h @@ -498,6 +498,11 @@ public: flush_one(); } + _FORCE_INLINE_ void flush_if_pending() { + if (unlikely(read_ptr_and_epoch != write_ptr_and_epoch)) { + flush_all(); + } + } void flush_all() { //ERR_FAIL_COND(sync); lock(); diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index d26c445eb4..3edc73b1a9 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -79,8 +79,7 @@ class RID_Alloc : public RID_AllocBase { SpinLock spin_lock; -public: - RID make_rid(const T &p_value) { + _FORCE_INLINE_ RID _allocate_rid(const T *p_initializer) { if (THREAD_SAFE) { spin_lock.lock(); } @@ -115,15 +114,22 @@ public: uint32_t free_chunk = free_index / elements_in_chunk; uint32_t free_element = free_index % elements_in_chunk; - T *ptr = &chunks[free_chunk][free_element]; - memnew_placement(ptr, T(p_value)); + if (p_initializer) { + T *ptr = &chunks[free_chunk][free_element]; + memnew_placement(ptr, T(*p_initializer)); + } - uint32_t validator = (uint32_t)(_gen_id() & 0xFFFFFFFF); + uint32_t validator = (uint32_t)(_gen_id() & 0x7FFFFFFF); uint64_t id = validator; id <<= 32; id |= free_index; validator_chunks[free_chunk][free_element] = validator; + + if (!p_initializer) { + validator_chunks[free_chunk][free_element] |= 0x80000000; //mark uninitialized bit + } + alloc_count++; if (THREAD_SAFE) { @@ -133,7 +139,20 @@ public: return _make_from_id(id); } - _FORCE_INLINE_ T *getornull(const RID &p_rid) { +public: + RID make_rid(const T &p_value) { + return _allocate_rid(&p_value); + } + + //allocate but don't initialize, use initialize_rid afterwards + RID allocate_rid() { + return _allocate_rid(nullptr); + } + + _FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) { + if (p_rid == RID()) { + return nullptr; + } if (THREAD_SAFE) { spin_lock.lock(); } @@ -151,10 +170,32 @@ public: uint32_t idx_element = idx % elements_in_chunk; uint32_t validator = uint32_t(id >> 32); - if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { + + if (unlikely(p_initialize)) { + if (unlikely(!(validator_chunks[idx_chunk][idx_element] & 0x80000000))) { + if (THREAD_SAFE) { + spin_lock.unlock(); + } + ERR_FAIL_V_MSG(nullptr, "Initializing already initialized RID"); + } + + if (unlikely((validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) != validator)) { + if (THREAD_SAFE) { + spin_lock.unlock(); + } + ERR_FAIL_V_MSG(nullptr, "Attempting to initialize the wrong RID"); + return nullptr; + } + + validator_chunks[idx_chunk][idx_element] &= 0x7FFFFFFF; //initialized + + } else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { if (THREAD_SAFE) { spin_lock.unlock(); } + if (validator_chunks[idx_chunk][idx_element] & 0x80000000) { + ERR_FAIL_V_MSG(nullptr, "Attempting to use an uninitialized RID"); + } return nullptr; } @@ -166,6 +207,11 @@ public: return ptr; } + void initialize_rid(RID p_rid, const T &p_value) { + T *mem = getornull(p_rid, true); + ERR_FAIL_COND(!mem); + memnew_placement(mem, T(p_value)); + } _FORCE_INLINE_ bool owns(const RID &p_rid) { if (THREAD_SAFE) { @@ -186,7 +232,7 @@ public: uint32_t validator = uint32_t(id >> 32); - bool owned = validator_chunks[idx_chunk][idx_element] == validator; + bool owned = (validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) == validator; if (THREAD_SAFE) { spin_lock.unlock(); @@ -213,7 +259,12 @@ public: uint32_t idx_element = idx % elements_in_chunk; uint32_t validator = uint32_t(id >> 32); - if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { + if (unlikely(validator_chunks[idx_chunk][idx_element] & 0x80000000)) { + if (THREAD_SAFE) { + spin_lock.unlock(); + } + ERR_FAIL_MSG("Attempted to free an uninitialized or invalid RID"); + } else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) { if (THREAD_SAFE) { spin_lock.unlock(); } @@ -330,6 +381,14 @@ public: return alloc.make_rid(p_ptr); } + _FORCE_INLINE_ RID allocate_rid() { + return alloc.allocate_rid(); + } + + _FORCE_INLINE_ void initialize_rid(RID p_rid, T *p_ptr) { + alloc.initialize_rid(p_rid, p_ptr); + } + _FORCE_INLINE_ T *getornull(const RID &p_rid) { T **ptr = alloc.getornull(p_rid); if (unlikely(!ptr)) { @@ -338,6 +397,12 @@ public: return *ptr; } + _FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) { + T **ptr = alloc.getornull(p_rid); + ERR_FAIL_COND(!ptr); + *ptr = p_new_ptr; + } + _FORCE_INLINE_ bool owns(const RID &p_rid) { return alloc.owns(p_rid); } @@ -379,6 +444,14 @@ public: return alloc.make_rid(p_ptr); } + _FORCE_INLINE_ RID allocate_rid() { + return alloc.allocate_rid(); + } + + _FORCE_INLINE_ void initialize_rid(RID p_rid, const T &p_ptr) { + alloc.initialize_rid(p_rid, p_ptr); + } + _FORCE_INLINE_ T *getornull(const RID &p_rid) { return alloc.getornull(p_rid); } diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 48916f941e..9a2922a777 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -35,6 +35,7 @@ #include "core/object/script_language.h" #include "core/templates/hashfuncs.h" #include "core/templates/vector.h" +#include "core/variant/callable.h" #include "core/variant/variant.h" class ArrayPrivate { @@ -371,25 +372,22 @@ void Array::sort() { } struct _ArrayVariantSortCustom { - Object *obj = nullptr; - StringName func; + Callable func; _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { const Variant *args[2] = { &p_l, &p_r }; Callable::CallError err; - bool res = obj->call(func, args, 2, err); - if (err.error != Callable::CallError::CALL_OK) { - res = false; - } + Variant res; + func.call(args, 2, res, err); + ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false, + "Error calling sorting method: " + Variant::get_callable_error_text(func, args, 1, err)); return res; } }; -void Array::sort_custom(Object *p_obj, const StringName &p_function) { - ERR_FAIL_NULL(p_obj); +void Array::sort_custom(Callable p_callable) { SortArray<Variant, _ArrayVariantSortCustom, true> avs; - avs.compare.obj = p_obj; - avs.compare.func = p_function; + avs.compare.func = p_callable; avs.sort(_p->array.ptrw(), _p->array.size()); } @@ -438,13 +436,11 @@ int Array::bsearch(const Variant &p_value, bool p_before) { return bisect(_p->array, p_value, p_before, _ArrayVariantSort()); } -int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { +int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) { ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); - ERR_FAIL_NULL_V(p_obj, 0); _ArrayVariantSortCustom less; - less.obj = p_obj; - less.func = p_function; + less.func = p_callable; return bisect(_p->array, p_value, p_before, less); } diff --git a/core/variant/array.h b/core/variant/array.h index 26de5477b4..d8f2402330 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -37,6 +37,7 @@ class Variant; class ArrayPrivate; class Object; class StringName; +class Callable; class Array { mutable ArrayPrivate *_p; @@ -78,10 +79,10 @@ public: Variant back() const; void sort(); - void sort_custom(Object *p_obj, const StringName &p_function); + void sort_custom(Callable p_callable); void shuffle(); int bsearch(const Variant &p_value, bool p_before = true); - int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true); + int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true); void invert(); int find(const Variant &p_value, int p_from = 0) const; diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 7824776fdb..015cee09a7 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -2023,7 +2023,7 @@ Variant::operator Color() const { if (type == COLOR) { return *reinterpret_cast<const Color *>(_data._mem); } else if (type == STRING) { - return Color::html(operator String()); + return Color(operator String()); } else if (type == INT) { return Color::hex(operator int()); } else { diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 2fd8134fbd..8f2cba138b 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1298,10 +1298,10 @@ static void _register_variant_builtin_methods() { bind_method(Array, pop_back, sarray(), varray()); bind_method(Array, pop_front, sarray(), varray()); bind_method(Array, sort, sarray(), varray()); - bind_method(Array, sort_custom, sarray("obj", "func"), varray()); + bind_method(Array, sort_custom, sarray("func"), varray()); bind_method(Array, shuffle, sarray(), varray()); bind_method(Array, bsearch, sarray("value", "before"), varray(true)); - bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true)); + bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true)); bind_method(Array, invert, sarray(), varray()); bind_method(Array, duplicate, sarray("deep"), varray(false)); bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 9835734583..52f9f6060e 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -688,6 +688,8 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Color, Color, double>>(sarray("from", "alpha")); add_constructor<VariantConstructor<Color, double, double, double>>(sarray("r", "g", "b")); add_constructor<VariantConstructor<Color, double, double, double, double>>(sarray("r", "g", "b", "a")); + add_constructor<VariantConstructor<Color, String>>(sarray("code")); + add_constructor<VariantConstructor<Color, String, double>>(sarray("code", "alpha")); add_constructor<VariantConstructNoArgs<StringName>>(sarray()); add_constructor<VariantConstructor<StringName, StringName>>(sarray("from")); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index bf81362e79..e5bcc773fe 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2147,7 +2147,25 @@ <constant name="JOY_BUTTON_DPAD_RIGHT" value="14" enum="JoyButtonList"> Game controller D-pad right button. </constant> - <constant name="JOY_BUTTON_SDL_MAX" value="15" enum="JoyButtonList"> + <constant name="JOY_BUTTON_MISC1" value="15" enum="JoyButtonList"> + Game controller SDL miscellaneous button. Corresponds to Xbox share button, PS5 microphone button, Nintendo capture button. + </constant> + <constant name="JOY_BUTTON_PADDLE1" value="16" enum="JoyButtonList"> + Game controller SDL paddle 1 button. + </constant> + <constant name="JOY_BUTTON_PADDLE2" value="17" enum="JoyButtonList"> + Game controller SDL paddle 2 button. + </constant> + <constant name="JOY_BUTTON_PADDLE3" value="18" enum="JoyButtonList"> + Game controller SDL paddle 3 button. + </constant> + <constant name="JOY_BUTTON_PADDLE4" value="19" enum="JoyButtonList"> + Game controller SDL paddle 4 button. + </constant> + <constant name="JOY_BUTTON_TOUCHPAD" value="20" enum="JoyButtonList"> + Game controller SDL touchpad button. + </constant> + <constant name="JOY_BUTTON_SDL_MAX" value="21" enum="JoyButtonList"> The number of SDL game controller buttons. </constant> <constant name="JOY_BUTTON_MAX" value="36" enum="JoyButtonList"> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index de3d89ee0f..cea5360234 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -191,11 +191,9 @@ </return> <argument index="0" name="value" type="Variant"> </argument> - <argument index="1" name="obj" type="Object"> + <argument index="1" name="func" type="Callable"> </argument> - <argument index="2" name="func" type="StringName"> - </argument> - <argument index="3" name="before" type="bool" default="true"> + <argument index="2" name="before" type="bool" default="true"> </argument> <description> Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise. @@ -537,12 +535,10 @@ <method name="sort_custom"> <return type="void"> </return> - <argument index="0" name="obj" type="Object"> - </argument> - <argument index="1" name="func" type="StringName"> + <argument index="0" name="func" type="Callable"> </argument> <description> - Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. + Sorts the array using a custom method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. [b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior. [codeblocks] [gdscript] @@ -553,7 +549,7 @@ return false var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]] - my_items.sort_custom(MyCustomSorter, "sort_ascending") + my_items.sort_custom(MyCustomSorter.sort_ascending) print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]]. [/gdscript] [csharp] diff --git a/doc/classes/AudioEffectCapture.xml b/doc/classes/AudioEffectCapture.xml new file mode 100644 index 0000000000..cf3d87c2e4 --- /dev/null +++ b/doc/classes/AudioEffectCapture.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="AudioEffectCapture" inherits="AudioEffect" version="4.0"> + <brief_description> + Captures audio from an audio bus in real-time. + </brief_description> + <description> + AudioEffectCapture is an AudioEffect which copies all audio frames from the attached audio effect bus into its internal ring buffer. + Application code should consume these audio frames from this ring buffer using [method get_buffer] and process it as needed, for example to capture data from a microphone, implement application defined effects, or to transmit audio over the network. + </description> + <tutorials> + </tutorials> + <methods> + <method name="can_get_buffer" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="frames" type="int"> + </argument> + <description> + Returns [code]true[/code] if at least [code]frames[/code] audio frames are available to read in the internal ring buffer. + </description> + </method> + <method name="clear_buffer"> + <return type="void"> + </return> + <description> + Clears the internal ring buffer. + </description> + </method> + <method name="get_buffer"> + <return type="PackedVector2Array"> + </return> + <argument index="0" name="frames" type="int"> + </argument> + <description> + Gets the next [code]frames[/code] audio samples from the internal ring buffer. + Returns a [PackedVector2Array] containing exactly [code]frames[/code] audio samples if available, or an empty [PackedVector2Array] if insufficient data was available. + </description> + </method> + <method name="get_buffer_length_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the total size of the internal ring buffer in frames. + </description> + </method> + <method name="get_discarded_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of audio frames discarded from the audio bus due to full buffer. + </description> + </method> + <method name="get_frames_available" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of frames available to read using [method get_buffer]. + </description> + </method> + <method name="get_pushed_frames" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of audio frames inserted from the audio bus. + </description> + </method> + </methods> + <members> + <member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="0.1"> + Length of the internal ring buffer, in seconds. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/CodeHighlighter.xml b/doc/classes/CodeHighlighter.xml index 7a1dad547b..f078e4e5b0 100644 --- a/doc/classes/CodeHighlighter.xml +++ b/doc/classes/CodeHighlighter.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CodeHighlighter" inherits="SyntaxHighlighter" version="4.0"> <brief_description> + A syntax highlighter for code. </brief_description> <description> + A syntax highlighter for code. </description> <tutorials> </tutorials> @@ -10,15 +12,18 @@ <method name="add_color_region"> <return type="void"> </return> - <argument index="0" name="p_start_key" type="String"> + <argument index="0" name="start_key" type="String"> </argument> - <argument index="1" name="p_end_key" type="String"> + <argument index="1" name="end_key" type="String"> </argument> - <argument index="2" name="p_color" type="Color"> + <argument index="2" name="color" type="Color"> </argument> - <argument index="3" name="p_line_only" type="bool" default="false"> + <argument index="3" name="line_only" type="bool" default="false"> </argument> <description> + Adds a color region such as comments or strings. + Both the start and end keys must be symbols. Only the start key has to be unique. + Line only denotes if the region should continue until the end of the line or carry over on to the next line. If the end key is blank this is automatically set to [code]true[/code]. </description> </method> <method name="add_keyword_color"> @@ -29,6 +34,8 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color for a keyword. + The keyword cannot contain any symbols except '_'. </description> </method> <method name="add_member_keyword_color"> @@ -39,24 +46,30 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color for a member keyword. + The member keyword cannot contain any symbols except '_'. + It will not be highlighted if preceded by a '.'. </description> </method> <method name="clear_color_regions"> <return type="void"> </return> <description> + Removes all color regions. </description> </method> <method name="clear_keyword_colors"> <return type="void"> </return> <description> + Removes all keywords. </description> </method> <method name="clear_member_keyword_colors"> <return type="void"> </return> <description> + Removes all member keywords. </description> </method> <method name="get_keyword_color" qualifiers="const"> @@ -65,6 +78,7 @@ <argument index="0" name="keyword" type="String"> </argument> <description> + Returns the color for a keyword. </description> </method> <method name="get_member_keyword_color" qualifiers="const"> @@ -73,14 +87,16 @@ <argument index="0" name="member_keyword" type="String"> </argument> <description> + Returns the color for a member keyword. </description> </method> <method name="has_color_region" qualifiers="const"> <return type="bool"> </return> - <argument index="0" name="p_start_key" type="String"> + <argument index="0" name="start_key" type="String"> </argument> <description> + Return [code]true[/code] if the start key exists, else [code]false[/code]. </description> </method> <method name="has_keyword_color" qualifiers="const"> @@ -89,6 +105,7 @@ <argument index="0" name="keyword" type="String"> </argument> <description> + Return [code]true[/code] if the keyword exists, else [code]false[/code]. </description> </method> <method name="has_member_keyword_color" qualifiers="const"> @@ -97,14 +114,16 @@ <argument index="0" name="member_keyword" type="String"> </argument> <description> + Return [code]true[/code] if the member keyword exists, else [code]false[/code]. </description> </method> <method name="remove_color_region"> <return type="void"> </return> - <argument index="0" name="p_start_key" type="String"> + <argument index="0" name="start_key" type="String"> </argument> <description> + Removes the color region that uses that start key. </description> </method> <method name="remove_keyword_color"> @@ -113,6 +132,7 @@ <argument index="0" name="keyword" type="String"> </argument> <description> + Removes the keyword. </description> </method> <method name="remove_member_keyword_color"> @@ -121,23 +141,31 @@ <argument index="0" name="member_keyword" type="String"> </argument> <description> + Removes the member keyword. </description> </method> </methods> <members> <member name="color_regions" type="Dictionary" setter="set_color_regions" getter="get_color_regions" default="{}"> + Sets the color regions. All existing regions will be removed. The [Dictionary] key is the region start and end key, separated by a space. The value is the region color. </member> <member name="function_color" type="Color" setter="set_function_color" getter="get_function_color" default="Color( 0, 0, 0, 1 )"> + Sets color for functions. A function is a non-keyword string followed by a '('. </member> <member name="keyword_colors" type="Dictionary" setter="set_keyword_colors" getter="get_keyword_colors" default="{}"> + Sets the keyword colors. All existing keywords will be removed. The [Dictionary] key is the keyword. The value is the keyword color. </member> <member name="member_keyword_colors" type="Dictionary" setter="set_member_keyword_colors" getter="get_member_keyword_colors" default="{}"> + Sets the member keyword colors. All existing member keyword will be removed. The [Dictionary] key is the member keyword. The value is the member keyword color. </member> <member name="member_variable_color" type="Color" setter="set_member_variable_color" getter="get_member_variable_color" default="Color( 0, 0, 0, 1 )"> + Sets color for member variables. A member variable is non-keyword, non-function string proceeded with a '.'. </member> <member name="number_color" type="Color" setter="set_number_color" getter="get_number_color" default="Color( 0, 0, 0, 1 )"> + Sets the color for numbers. </member> <member name="symbol_color" type="Color" setter="set_symbol_color" getter="get_symbol_color" default="Color( 0, 0, 0, 1 )"> + Sets the color for symbols. </member> </members> <constants> diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 8af5f29b65..ce88e0ae88 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -5,7 +5,7 @@ </brief_description> <description> A color represented by red, green, blue, and alpha (RGBA) components. The alpha component is often used for transparency. Values are in floating-point and usually range from 0 to 1. Some properties (such as CanvasItem.modulate) may accept values greater than 1 (overbright or HDR colors). - You can also create a color from standardized color names by using [code]ColorN[/code] ([b]FIXME:[/b] No longer true, a Color(String) constructor should be re-implemented for that) or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url]. + You can also create a color from standardized color names by using the string constructor or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url]. If you want to supply values in a range of 0 to 255, you should use [method @GDScript.Color8]. [b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it's equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code]. [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/color_constants.png]Color constants cheatsheet[/url] @@ -54,6 +54,26 @@ <method name="Color" qualifiers="constructor"> <return type="Color"> </return> + <argument index="0" name="code" type="String"> + </argument> + <argument index="1" name="alpha" type="float"> + </argument> + <description> + Constructs a [Color] either from an HTML color code or from a standardized color name, with [code]alpha[/code] on the range of 0 to 1. Supported color names are the same as the constants. + </description> + </method> + <method name="Color" qualifiers="constructor"> + <return type="Color"> + </return> + <argument index="0" name="code" type="String"> + </argument> + <description> + Constructs a [Color] either from an HTML color code or from a standardized color name. Supported color names are the same as the constants. + </description> + </method> + <method name="Color" qualifiers="constructor"> + <return type="Color"> + </return> <argument index="0" name="r" type="float"> </argument> <argument index="1" name="g" type="float"> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index d94e495a5e..e5285587eb 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -16,8 +16,9 @@ [b]Note:[/b] Theme items are [i]not[/i] [Object] properties. This means you can't access their values using [method Object.get] and [method Object.set]. Instead, use the [code]get_theme_*[/code] and [code]add_theme_*_override[/code] methods provided by this class. </description> <tutorials> - <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/gui/index.html</link> + <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/ui/index.html</link> <link title="Custom drawing in 2D">https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link> + <link title="Control node gallery">https://docs.godotengine.org/en/latest/tutorials/ui/control_node_gallery.html</link> <link title="All GUI Demos">https://github.com/godotengine/godot-demo-projects/tree/master/gui</link> </tutorials> <methods> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index e5401134bf..aa64ab4043 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -16,7 +16,7 @@ return "my.special.plugin" func get_visible_name(): - return "Special Mesh Importer" + return "Special Mesh" func get_recognized_extensions(): return ["special", "spec"] @@ -44,8 +44,7 @@ # Fill the Mesh with data read in "file", left as an exercise to the reader. var filename = save_path + "." + get_save_extension() - ResourceSaver.save(filename, mesh) - return OK + return ResourceSaver.save(filename, mesh) [/gdscript] [csharp] using Godot; @@ -60,7 +59,7 @@ public override String GetVisibleName() { - return "Special Mesh Importer"; + return "Special Mesh"; } public override Godot.Collections.Array GetRecognizedExtensions() @@ -104,8 +103,7 @@ var mesh = new ArrayMesh(); // Fill the Mesh with data read in "file", left as an exercise to the reader. String filename = savePath + "." + GetSaveExtension(); - ResourceSaver.Save(filename, mesh); - return (int)Error.Ok; + return (int)ResourceSaver.Save(filename, mesh); } } [/csharp] @@ -220,7 +218,7 @@ <return type="String"> </return> <description> - Gets the name to display in the import window. + Gets the name to display in the import window. You should choose this name as a continuation to "Import as", e.g. "Import as Special Mesh". </description> </method> <method name="import" qualifiers="virtual"> diff --git a/doc/classes/EditorSyntaxHighlighter.xml b/doc/classes/EditorSyntaxHighlighter.xml index 103d95e1d6..b80e81928f 100644 --- a/doc/classes/EditorSyntaxHighlighter.xml +++ b/doc/classes/EditorSyntaxHighlighter.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorSyntaxHighlighter" inherits="SyntaxHighlighter" version="4.0"> <brief_description> + Base Syntax highlighter resource for the [ScriptEditor]. </brief_description> <description> + Base syntax highlighter resource all editor syntax highlighters extend from, it is used in the [ScriptEditor]. + Add a syntax highlighter to an individual script by calling [method ScriptEditorBase.add_syntax_highlighter]. To apply to all scripts on open, call [method ScriptEditor.register_syntax_highlighter] </description> <tutorials> </tutorials> @@ -11,18 +14,21 @@ <return type="String"> </return> <description> + Virtual method which can be overridden to return the syntax highlighter name. </description> </method> <method name="_get_supported_extentions" qualifiers="virtual"> <return type="Array"> </return> <description> + Virtual method which can be overridden to return the supported file extensions. </description> </method> <method name="_get_supported_languages" qualifiers="virtual"> <return type="Array"> </return> <description> + Virtual method which can be overridden to return the supported language names. </description> </method> </methods> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 9dd4ecc37b..a986ec35c6 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -265,7 +265,9 @@ </member> <member name="volumetric_fog_light_energy" type="float" setter="set_volumetric_fog_light_energy" getter="get_volumetric_fog_light_energy" default="1.0"> </member> - <member name="volumetric_fog_shadow_filter" type="int" setter="set_volumetric_fog_shadow_filter" getter="get_volumetric_fog_shadow_filter" enum="Environment.VolumetricFogShadowFilter" default="1"> + <member name="volumetric_fog_temporal_reprojection_amount" type="float" setter="set_volumetric_fog_temporal_reprojection_amount" getter="get_volumetric_fog_temporal_reprojection_amount" default="0.9"> + </member> + <member name="volumetric_fog_temporal_reprojection_enabled" type="bool" setter="set_volumetric_fog_temporal_reprojection_enabled" getter="is_volumetric_fog_temporal_reprojection_enabled" default="true"> </member> </members> <constants> diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 2f7ac551cf..ff03f44789 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -481,8 +481,9 @@ </methods> <members> <member name="endian_swap" type="bool" setter="set_endian_swap" getter="get_endian_swap" default="false"> - If [code]true[/code], the file's endianness is swapped. Use this if you're dealing with files written on big-endian machines. - [b]Note:[/b] This is about the file format, not CPU type. This is always reset to [code]false[/code] whenever you open the file. + If [code]true[/code], the file is read with big-endian [url=https://en.wikipedia.org/wiki/Endianness]endianness[/url]. If [code]false[/code], the file is read with little-endian endianness. If in doubt, leave this to [code]false[/code] as most files are written with little-endian endianness. + [b]Note:[/b] [member endian_swap] is only about the file format, not the CPU type. The CPU endianness doesn't affect the default endianness for files written. + [b]Note:[/b] This is always reset to [code]false[/code] whenever you open the file. Therefore, you must set [member endian_swap] [i]after[/i] opening the file, not before. </member> </members> <constants> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 4b0ea4dcb1..3a126d89e9 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -260,6 +260,13 @@ Emitted when the GraphNode is moved. </description> </signal> + <signal name="slot_updated"> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Emitted when any GraphNode's slot is updated. + </description> + </signal> <signal name="raise_request"> <description> Emitted when the GraphNode is requested to be displayed over other ones. Happens on focusing (clicking into) the GraphNode. diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 6c008e4f7e..111473e098 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -78,7 +78,7 @@ <member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false"> If [code]true[/code], the light will cast shadows. </member> - <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="1.0"> + <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="0.1"> </member> <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="2.0"> Offsets the lookup into the shadow map by the object's normal. This can be used to reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index e8913f2623..5f0d6462e2 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -623,10 +623,11 @@ </return> <argument index="0" name="node" type="Node"> </argument> - <argument index="1" name="keep_data" type="bool" default="false"> + <argument index="1" name="keep_groups" type="bool" default="false"> </argument> <description> Replaces a node in a scene by the given one. Subscriptions that pass through this node will be lost. + If [code]keep_groups[/code] is [code]true[/code], the [code]node[/code] is added to the same groups that the replaced node is in. </description> </method> <method name="request_ready"> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 6ff7e34194..f55b8597dd 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -10,11 +10,20 @@ Some classes that extend Object add memory management. This is the case of [Reference], which counts references and deletes itself automatically when no longer referenced. [Node], another fundamental type, deletes all its children when freed from memory. Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them. Property membership can be tested directly in GDScript using [code]in[/code]: - [codeblock] + [codeblocks] + [gdscript] var n = Node2D.new() print("position" in n) # Prints "True". print("other_property" in n) # Prints "False". - [/codeblock] + [/gdscript] + [csharp] + var node = new Node2D(); + // C# has no direct equivalent to GDScript's `in` operator here, but we + // can achieve the same behavior by performing `Get` with a null check. + GD.Print(node.Get("position") != null); // Prints "True". + GD.Print(node.Get("other_property") != null); // Prints "False". + [/csharp] + [/codeblocks] The [code]in[/code] operator will evaluate to [code]true[/code] as long as the key exists, even if the value is [code]null[/code]. Objects also receive notifications. Notifications are a simple way to notify the object about different events, so they can all be handled together. See [method _notification]. [b]Note:[/b] Unlike references to a [Reference], references to an Object stored in a variable can become invalid without warning. Therefore, it's recommended to use [Reference] for data classes instead of [Object]. @@ -96,9 +105,16 @@ </argument> <description> Calls the [code]method[/code] on the object and returns the result. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example: - [codeblock] - call("set", "position", Vector2(42.0, 0.0)) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.call("set", "position", Vector2(42, 0)) + [/gdscript] + [csharp] + var node = new Node2D(); + node.Call("set", "position", new Vector2(42, 0)); + [/csharp] + [/codeblocks] [b]Note:[/b] In C#, the method name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined methods where you should use the same convention as in the C# source (typically PascalCase). </description> </method> @@ -109,9 +125,16 @@ </argument> <description> Calls the [code]method[/code] on the object during idle time. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example: - [codeblock] - call_deferred("set", "position", Vector2(42.0, 0.0)) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.call_deferred("set", "position", Vector2(42, 0)) + [/gdscript] + [csharp] + var node = new Node2D(); + node.CallDeferred("set", "position", new Vector2(42, 0)); + [/csharp] + [/codeblocks] [b]Note:[/b] In C#, the method name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined methods where you should use the same convention as in the C# source (typically PascalCase). </description> </method> @@ -124,9 +147,16 @@ </argument> <description> Calls the [code]method[/code] on the object and returns the result. Contrarily to [method call], this method does not support a variable number of arguments but expects all parameters to be via a single [Array]. - [codeblock] - callv("set", [ "position", Vector2(42.0, 0.0) ]) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.callv("set", ["position", Vector2(42, 0)]) + [/gdscript] + [csharp] + var node = new Node2D(); + node.Callv("set", new Godot.Collections.Array { "position", new Vector2(42, 0) }); + [/csharp] + [/codeblocks] </description> </method> <method name="can_translate_messages" qualifiers="const"> @@ -148,23 +178,140 @@ <argument index="3" name="flags" type="int" default="0"> </argument> <description> - [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated. - Connects a [code]signal[/code] to a [code]method[/code] on a [code]target[/code] object. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. - A [code]signal[/code] can only be connected once to a [code]method[/code]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. - If the [code]target[/code] is destroyed in the game's lifecycle, the connection will be lost. - Examples: - [codeblock] - connect("pressed", self, "_on_Button_pressed") # BaseButton signal - connect("text_entered", self, "_on_LineEdit_text_entered") # LineEdit signal - connect("hit", self, "_on_Player_hit", [ weapon_type, damage ]) # User-defined signal - [/codeblock] - An example of the relationship between [code]binds[/code] passed to [method connect] and parameters used when calling [method emit_signal]: - [codeblock] - connect("hit", self, "_on_Player_hit", [ weapon_type, damage ]) # weapon_type and damage are passed last - emit_signal("hit", "Dark lord", 5) # "Dark lord" and 5 are passed first - func _on_Player_hit(hit_by, level, weapon_type, damage): - print("Hit by %s (lvl %d) with weapon %s for %d damage" % [hit_by, level, weapon_type, damage]) - [/codeblock] + Connects a [code]signal[/code] to a [code]callable[/code]. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the [Callable]'s method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants. + [b]Note:[/b] This method is the legacy implementation for connecting signals. The recommend modern approach is to use [method Signal.connect] and to use [method Callable.bind] to add and validate parameter binds. Both syntaxes are shown below. + A signal can only be connected once to a [Callable]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections. + If the callable's target is destroyed in the game's lifecycle, the connection will be lost. + [b]Examples with recommended syntax:[/b] + Connecting signals is one of the most common operations in Godot and the API gives many options to do so, which are described further down. The code block below shows the recommended approach for both GDScript and C#. + [codeblocks] + [gdscript] + func _ready(): + var button = Button.new() + # `button_down` here is a Signal object, and we thus call the Signal.connect() method, + # not Object.connect(). See discussion below for a more in-depth overview of the API. + button.button_down.connect(_on_button_down) + + # This assumes that a `Player` class exists which defines a `hit` signal. + var player = Player.new() + # We use Signal.connect() again, and we also use the Callable.bind() method which + # returns a new Callable with the parameter binds. + player.hit.connect(_on_player_hit.bind("sword", 100)) + + func _on_button_down(): + print("Button down!") + + func _on_player_hit(weapon_type, damage): + print("Hit with weapon %s for %d damage." % [weapon_type, damage]) + [/gdscript] + [csharp] + public override void _Ready() + { + var button = new Button(); + // C# supports passing signals as events, so we can use this idiomatic construct: + button.ButtonDown += OnButtonDown; + + // This assumes that a `Player` class exists which defines a `Hit` signal. + var player = new Player(); + // Signals as events (`player.Hit += OnPlayerHit;`) do not support argument binding. You have to use: + player.Hit.Connect(OnPlayerHit, new Godot.Collections.Array {"sword", 100 }); + } + + private void OnButtonDown() + { + GD.Print("Button down!"); + } + + private void OnPlayerHit(string weaponType, int damage) + { + GD.Print(String.Format("Hit with weapon {0} for {1} damage.", weaponType, damage)); + } + [/csharp] + [/codeblocks] + [b][code]Object.connect()[/code] or [code]Signal.connect()[/code]?[/b] + As seen above, the recommended method to connect signals is not [method Object.connect]. The code block below shows the four options for connecting signals, using either this legacy method or the recommended [method Signal.connect], and using either an implicit [Callable] or a manually defined one. + [codeblocks] + [gdscript] + func _ready(): + var button = Button.new() + # Option 1: Object.connect() with an implicit Callable for the defined function. + button.connect("button_down", _on_button_down) + # Option 2: Object.connect() with a constructed Callable using a target object and method name. + button.connect("button_down", Callable(self, "_on_button_down")) + # Option 3: Signal.connect() with an implicit Callable for the defined function. + button.button_down.connect(_on_button_down) + # Option 4: Signal.connect() with a constructed Callable using a target object and method name. + button.button_down.connect(Callable(self, "_on_button_down")) + + func _on_button_down(): + print("Button down!") + [/gdscript] + [csharp] + public override void _Ready() + { + var button = new Button(); + // Option 1: Object.Connect() with an implicit Callable for the defined function. + button.Connect("button_down", OnButtonDown); + // Option 2: Object.connect() with a constructed Callable using a target object and method name. + button.Connect("button_down", new Callable(self, nameof(OnButtonDown))); + // Option 3: Signal.connect() with an implicit Callable for the defined function. + button.ButtonDown.Connect(OnButtonDown); + // Option 3b: In C#, we can use signals as events and connect with this more idiomatic syntax: + button.ButtonDown += OnButtonDown; + // Option 4: Signal.connect() with a constructed Callable using a target object and method name. + button.ButtonDown.Connect(new Callable(self, nameof(OnButtonDown))); + } + + private void OnButtonDown() + { + GD.Print("Button down!"); + } + [/csharp] + [/codeblocks] + While all options have the same outcome ([code]button[/code]'s [signal BaseButton.button_down] signal will be connected to [code]_on_button_down[/code]), option 3 offers the best validation: it will throw a compile-time error if either the [code]button_down[/code] signal or the [code]_on_button_down[/code] callable are undefined. On the other hand, option 2 only relies on string names and will only be able to validate either names at runtime: it will throw a runtime error if [code]"button_down"[/code] doesn't correspond to a signal, or if [code]"_on_button_down"[/code] is not a registered method in the object [code]self[/code]. The main reason for using options 1, 2, or 4 would be if you actually need to use strings (e.g. to connect signals programmatically based on strings read from a configuration file). Otherwise, option 3 is the recommended (and fastest) method. + [b]Parameter bindings and passing:[/b] + For legacy or language-specific reasons, there are also several ways to bind parameters to signals. One can pass a [code]binds[/code] [Array] to [method Object.connect] or [method Signal.connect], or use the recommended [method Callable.bind] method to create a new callable from an existing one, with the given parameter binds. + One can also pass additional parameters when emitting the signal with [method emit_signal]. The examples below show the relationship between those two types of parameters. + [codeblocks] + [gdscript] + func _ready(): + # This assumes that a `Player` class exists which defines a `hit` signal. + var player = Player.new() + # Option 1: Using Callable.bind(). + player.hit.connect(_on_player_hit.bind("sword", 100)) + # Option 2: Using a `binds` Array in Signal.connect() (same syntax for Object.connect()). + player.hit.connect(_on_player_hit, ["sword", 100]) + + # Parameters added when emitting the signal are passed first. + player.emit_signal("hit", "Dark lord", 5) + + # Four arguments, since we pass two when emitting (hit_by, level) + # and two when connecting (weapon_type, damage). + func _on_player_hit(hit_by, level, weapon_type, damage): + print("Hit by %s (level %d) with weapon %s for %d damage." % [hit_by, level, weapon_type, damage]) + [/gdscript] + [csharp] + public override void _Ready() + { + // This assumes that a `Player` class exists which defines a `Hit` signal. + var player = new Player(); + // Option 1: Using Callable.Bind(). This way we can still use signals as events. + player.Hit += OnPlayerHit.Bind("sword", 100); + // Option 2: Using a `binds` Array in Signal.Connect() (same syntax for Object.Connect()). + player.Hit.Connect(OnPlayerHit, new Godot.Collections.Array{ "sword", 100 }); + + // Parameters added when emitting the signal are passed first. + player.EmitSignal("hit", "Dark lord", 5); + } + + // Four arguments, since we pass two when emitting (hitBy, level) + // and two when connecting (weaponType, damage). + private void OnPlayerHit(string hitBy, int level, string weaponType, int damage) + { + GD.Print(String.Format("Hit by {0} (level {1}) with weapon {2} for {3} damage.", hitBy, level, weaponType, damage)); + } + [/csharp] + [/codeblocks] </description> </method> <method name="disconnect"> @@ -175,8 +322,7 @@ <argument index="1" name="callable" type="Callable"> </argument> <description> - [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated. - Disconnects a [code]signal[/code] from a [code]method[/code] on the given [code]target[/code]. + Disconnects a [code]signal[/code] from a given [code]callable[/code]. If you try to disconnect a connection that does not exist, the method will throw an error. Use [method is_connected] to ensure that the connection exists. </description> </method> @@ -187,10 +333,16 @@ </argument> <description> Emits the given [code]signal[/code]. The signal must exist, so it should be a built-in signal of this class or one of its parent classes, or a user-defined signal. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example: - [codeblock] - emit_signal("hit", weapon_type, damage) + [codeblocks] + [gdscript] + emit_signal("hit", "sword", 100) emit_signal("game_over") - [/codeblock] + [/gdscript] + [csharp] + EmitSignal("hit", "sword", 100); + EmitSignal("game_over"); + [/csharp] + [/codeblocks] </description> </method> <method name="free"> @@ -359,8 +511,7 @@ <argument index="1" name="callable" type="Callable"> </argument> <description> - [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated. - Returns [code]true[/code] if a connection exists for a given [code]signal[/code], [code]target[/code], and [code]method[/code]. + Returns [code]true[/code] if a connection exists for a given [code]signal[/code] and [code]callable[/code]. </description> </method> <method name="is_queued_for_deletion" qualifiers="const"> @@ -440,11 +591,20 @@ </argument> <description> Assigns a new value to the property identified by the [NodePath]. The node path should be relative to the current object and can use the colon character ([code]:[/code]) to access nested properties. Example: - [codeblock] - set_indexed("position", Vector2(42, 0)) - set_indexed("position:y", -10) - print(position) # (42, -10) - [/codeblock] + [codeblocks] + [gdscript] + var node = Node2D.new() + node.set_indexed("position", Vector2(42, 0)) + node.set_indexed("position:y", -10) + print(node.position) # (42, -10) + [/gdscript] + [csharp] + var node = new Node2D(); + node.SetIndexed("position", new Vector2(42, 0)); + node.SetIndexed("position:y", -10); + GD.Print(node.Position); // (42, -10) + [/csharp] + [/codeblocks] </description> </method> <method name="set_message_translation"> diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index d15bcfd114..1d9be7f165 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -5,7 +5,7 @@ </brief_description> <description> A simplified interface to a scene file. Provides access to operations and checks that can be performed on the scene resource itself. - Can be used to save a node to a file. When saving, the node as well as all the node it owns get saved (see [code]owner[/code] property on [Node]). + Can be used to save a node to a file. When saving, the node as well as all the nodes it owns get saved (see [code]owner[/code] property on [Node]). [b]Note:[/b] The node doesn't need to own itself. [b]Example of loading a saved scene:[/b] [codeblocks] diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index fc618206ed..be72f83406 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1088,9 +1088,6 @@ </member> <member name="rendering/lightmapper/probe_capture_update_speed" type="float" setter="" getter="" default="15"> </member> - <member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000"> - Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves. - </member> <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600"> </member> <member name="rendering/quality/2d/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false"> @@ -1306,11 +1303,7 @@ <member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1"> Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter. </member> - <member name="rendering/volumetric_fog/directional_shadow_shrink" type="int" setter="" getter="" default="512"> - </member> - <member name="rendering/volumetric_fog/positional_shadow_shrink" type="int" setter="" getter="" default="512"> - </member> - <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="0"> + <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="1"> </member> <member name="rendering/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128"> </member> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index d0fb2b9d47..84e307b852 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -74,6 +74,8 @@ <method name="compute_list_begin"> <return type="int"> </return> + <argument index="0" name="allow_draw_overlap" type="bool" default="false"> + </argument> <description> </description> </method> @@ -443,6 +445,24 @@ <description> </description> </method> + <method name="get_device_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_device_pipeline_cache_uuid" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_device_vendor_name" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> <method name="get_frame_delay" qualifiers="const"> <return type="int"> </return> @@ -823,6 +843,8 @@ </constant> <constant name="BARRIER_MASK_ALL" value="7"> </constant> + <constant name="BARRIER_MASK_NO_BARRIER" value="8"> + </constant> <constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat"> </constant> <constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat"> @@ -1587,13 +1609,15 @@ </constant> <constant name="INITIAL_ACTION_CLEAR_REGION" value="1" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_KEEP" value="2" enum="InitialAction"> + <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="2" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_KEEP" value="3" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_DROP" value="3" enum="InitialAction"> + <constant name="INITIAL_ACTION_DROP" value="4" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_CONTINUE" value="4" enum="InitialAction"> + <constant name="INITIAL_ACTION_CONTINUE" value="5" enum="InitialAction"> </constant> - <constant name="INITIAL_ACTION_MAX" value="5" enum="InitialAction"> + <constant name="INITIAL_ACTION_MAX" value="6" enum="InitialAction"> </constant> <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction"> </constant> diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index d5a32dd20c..28620bd29b 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -37,6 +37,7 @@ <return type="ScriptEditorBase"> </return> <description> + Returns the [ScriptEditorBase] object that the user is currently editing. </description> </method> <method name="get_current_script"> @@ -60,6 +61,7 @@ <return type="Array"> </return> <description> + Returns an array with all [ScriptEditorBase] objects which are currently open in editor. </description> </method> <method name="get_open_scripts" qualifiers="const"> @@ -95,6 +97,8 @@ <argument index="0" name="syntax_highlighter" type="EditorSyntaxHighlighter"> </argument> <description> + Registers the [EditorSyntaxHighlighter] to the editor, the [EditorSyntaxHighlighter] will be available on all open scripts. + [b]Note:[/b] Does not apply to scripts that are already opened. </description> </method> <method name="unregister_syntax_highlighter"> @@ -103,6 +107,8 @@ <argument index="0" name="syntax_highlighter" type="EditorSyntaxHighlighter"> </argument> <description> + Unregisters the [EditorSyntaxHighlighter] from the editor. + [b]Note:[/b] The [EditorSyntaxHighlighter] will still be applied to scripts that are already opened. </description> </method> </methods> diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml index 9968ae06c3..ee498de302 100644 --- a/doc/classes/ScriptEditorBase.xml +++ b/doc/classes/ScriptEditorBase.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ScriptEditorBase" inherits="VBoxContainer" version="4.0"> <brief_description> + Base editor for editing scripts in the [ScriptEditor]. </brief_description> <description> + Base editor for editing scripts in the [ScriptEditor], this does not include documentation items. </description> <tutorials> </tutorials> @@ -13,34 +15,40 @@ <argument index="0" name="highlighter" type="Object"> </argument> <description> + Adds a [EditorSyntaxHighlighter] to the open script. </description> </method> </methods> <signals> <signal name="edited_script_changed"> <description> + Emitted after script validation. For visual scripts on modification. </description> </signal> <signal name="go_to_help"> <argument index="0" name="what" type="String"> </argument> <description> + Emitted when the user requests a specific documentation page. </description> </signal> <signal name="name_changed"> <description> + Emitted after script validation or when the edited resource has changed. Not used by visual scripts. </description> </signal> <signal name="replace_in_files_requested"> <argument index="0" name="text" type="String"> </argument> <description> + Emitted when the user request to find and replace text in the file system. Not used by visual scripts. </description> </signal> <signal name="request_help"> <argument index="0" name="topic" type="String"> </argument> <description> + Emitted when the user requests contextual help. </description> </signal> <signal name="request_open_script_at_line"> @@ -49,16 +57,19 @@ <argument index="1" name="line" type="int"> </argument> <description> + Emitted when the user requests a script. </description> </signal> <signal name="request_save_history"> <description> + Emitted when the user contextual goto and the item is in the same script. </description> </signal> <signal name="search_in_files_requested"> <argument index="0" name="text" type="String"> </argument> <description> + Emitted when the user request to search text in the file system. Not used by visual scripts. </description> </signal> </signals> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index e10b65e309..331de4284e 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -155,8 +155,8 @@ <argument index="0" name="flip" type="bool" default="false"> </argument> <description> - Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. - Requires the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]. + Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. [method generate_normals] should be called [i]after[/i] generating geometry and [i]before[/i] committing the mesh using [method commit] or [method commit_to_arrays]. + [b]Note:[/b] [method generate_normals] only works if the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]. </description> </method> <method name="generate_tangents"> diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml index 2d6e3de02a..642d75fa9b 100644 --- a/doc/classes/SyntaxHighlighter.xml +++ b/doc/classes/SyntaxHighlighter.xml @@ -1,50 +1,83 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="SyntaxHighlighter" inherits="Resource" version="4.0"> <brief_description> + Base Syntax highlighter resource for [TextEdit]. </brief_description> <description> + Base syntax highlighter resource all syntax highlighters extend from, provides syntax highlighting data to [TextEdit]. + The associated [TextEdit] node will call into the [SyntaxHighlighter] on a as needed basis. + [b]Note:[/b] Each Syntax highlighter instance should not be shared across multiple [TextEdit] nodes. </description> <tutorials> </tutorials> <methods> + <method name="_clear_highlighting_cache" qualifiers="virtual"> + <return type="void"> + </return> + <description> + Virtual method which can be overridden to clear any local caches. + </description> + </method> <method name="_get_line_syntax_highlighting" qualifiers="virtual"> <return type="Dictionary"> </return> - <argument index="0" name="p_line" type="int"> + <argument index="0" name="line" type="int"> </argument> <description> + Virtual method which can be overridden to return syntax highlighting data. + See [method get_line_syntax_highlighting] for more details. </description> </method> <method name="_update_cache" qualifiers="virtual"> <return type="void"> </return> <description> + Virtual method which can be overridden to update any local caches. </description> </method> <method name="clear_highlighting_cache"> <return type="void"> </return> <description> + Clears all cached syntax highlighting data. + Then calls overridable method [method _clear_highlighting_cache]. </description> </method> <method name="get_line_syntax_highlighting"> <return type="Dictionary"> </return> - <argument index="0" name="p_line" type="int"> + <argument index="0" name="line" type="int"> </argument> <description> + Returns syntax highlighting data for a single line. If the line is not cached, calls [method _get_line_syntax_highlighting] to calculate the data. + The return [Dictionary] is column number to [Dictionary]. The column number notes the start of a region, the region will end if another region is found, or at the end of the line. The nested [Dictionary] contains the data for that region, currently only the key "color" is supported. + [b]Example return:[/b] + [codeblock] + var color_map = { + 0: { + "color": Color(1, 0, 0) + }, + 5: { + "color": Color(0, 1, 0) + } + } + [/codeblock] + This will color columns 0-4 red, and columns 5-eol in green. </description> </method> <method name="get_text_edit"> <return type="TextEdit"> </return> <description> + Returns the associated [TextEdit] node. </description> </method> <method name="update_cache"> <return type="void"> </return> <description> + Clears then updates the [SyntaxHighlighter] caches. Override [method _update_cache] for a callback. + [b]Note:[/b] This is called automatically when the associated [TextEdit] node, updates its own cache. </description> </method> </methods> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index af4543374a..539f7afbd8 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -725,6 +725,7 @@ Set additional options for BiDi override. </member> <member name="syntax_highlighter" type="SyntaxHighlighter" setter="set_syntax_highlighter" getter="get_syntax_highlighter"> + Sets the [SyntaxHighlighter] to use. </member> <member name="text" type="String" setter="set_text" getter="get_text" default=""""> String value of the [TextEdit]. @@ -914,7 +915,7 @@ </constants> <theme_items> <theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 0 )"> - Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] has to be enabled. + Sets the background [Color] of this [TextEdit]. </theme_item> <theme_item name="brace_mismatch_color" type="Color" default="Color( 1, 0.2, 0.2, 1 )"> </theme_item> diff --git a/doc/classes/VisualShaderNodeClamp.xml b/doc/classes/VisualShaderNodeClamp.xml new file mode 100644 index 0000000000..504171bb13 --- /dev/null +++ b/doc/classes/VisualShaderNodeClamp.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeClamp" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Clamps a value within the visual shader graph. + </brief_description> + <description> + Constrains a value to lie between [code]min[/code] and [code]max[/code] values. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeClamp.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_FLOAT" value="0" enum="OpType"> + A floating-point scalar. + </constant> + <constant name="OP_TYPE_INT" value="1" enum="OpType"> + An integer scalar. + </constant> + <constant name="OP_TYPE_VECTOR" value="2" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeIntFunc.xml b/doc/classes/VisualShaderNodeIntFunc.xml index 5c68c0ec71..a9f4144a01 100644 --- a/doc/classes/VisualShaderNodeIntFunc.xml +++ b/doc/classes/VisualShaderNodeIntFunc.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="3"> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="2"> A function to be applied to the scalar. See [enum Function] for options. </member> </members> @@ -19,13 +19,10 @@ <constant name="FUNC_ABS" value="0" enum="Function"> Returns the absolute value of the parameter. Translates to [code]abs(x)[/code] in the Godot Shader Language. </constant> - <constant name="FUNC_CLAMP" value="1" enum="Function"> - Constrains a parameter between [code]min[/code] and [code]max[/code]. Translates to [code]clamp(x, min, max)[/code] in the Godot Shader Language. - </constant> - <constant name="FUNC_NEGATE" value="2" enum="Function"> + <constant name="FUNC_NEGATE" value="1" enum="Function"> Negates the [code]x[/code] using [code]-(x)[/code]. </constant> - <constant name="FUNC_SIGN" value="3" enum="Function"> + <constant name="FUNC_SIGN" value="2" enum="Function"> Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language. </constant> </constants> diff --git a/doc/classes/VisualShaderNodeMix.xml b/doc/classes/VisualShaderNodeMix.xml new file mode 100644 index 0000000000..c70ac7e599 --- /dev/null +++ b/doc/classes/VisualShaderNodeMix.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeMix" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Linearly interpolates between two values within the visual shader graph. + </brief_description> + <description> + Translates to [code]mix(a, b, weight)[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeMix.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A scalar type. + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType"> + A vector type. [code]weight[/code] port is using a scalar type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeScalarClamp.xml b/doc/classes/VisualShaderNodeScalarClamp.xml deleted file mode 100644 index 7432e8dfca..0000000000 --- a/doc/classes/VisualShaderNodeScalarClamp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarClamp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Clamps a scalar value within the visual shader graph. - </brief_description> - <description> - Constrains a value to lie between [code]min[/code] and [code]max[/code] values. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarInterp.xml b/doc/classes/VisualShaderNodeScalarInterp.xml deleted file mode 100644 index 393ea70e1a..0000000000 --- a/doc/classes/VisualShaderNodeScalarInterp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarInterp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Linearly interpolates between two scalars within the visual shader graph. - </brief_description> - <description> - Translates to [code]mix(a, b, weight)[/code] in the shader language. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarSmoothStep.xml b/doc/classes/VisualShaderNodeScalarSmoothStep.xml deleted file mode 100644 index e619cc8571..0000000000 --- a/doc/classes/VisualShaderNodeScalarSmoothStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarSmoothStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a scalar SmoothStep function within the visual shader graph. - </brief_description> - <description> - Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarSwitch.xml b/doc/classes/VisualShaderNodeScalarSwitch.xml deleted file mode 100644 index 2ad5202745..0000000000 --- a/doc/classes/VisualShaderNodeScalarSwitch.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarSwitch" inherits="VisualShaderNodeSwitch" version="4.0"> - <brief_description> - A boolean/scalar function for use within the visual shader graph. - </brief_description> - <description> - Returns an associated scalar if the provided boolean value is [code]true[/code] or [code]false[/code]. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeSmoothStep.xml b/doc/classes/VisualShaderNodeSmoothStep.xml new file mode 100644 index 0000000000..fa22d16da8 --- /dev/null +++ b/doc/classes/VisualShaderNodeSmoothStep.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeSmoothStep" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Calculates a SmoothStep function within the visual shader graph. + </brief_description> + <description> + Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language. + Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeSmoothStep.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A scalar type. + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType"> + A vector type. [code]edge0[/code] and [code]edge1[/code] are using a scalar type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeStep.xml b/doc/classes/VisualShaderNodeStep.xml new file mode 100644 index 0000000000..694c144445 --- /dev/null +++ b/doc/classes/VisualShaderNodeStep.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeStep" inherits="VisualShaderNode" version="4.0"> + <brief_description> + Calculates a Step function within the visual shader graph. + </brief_description> + <description> + Translates to [code]step(edge, x)[/code] in the shader language. + Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeStep.OpType" default="0"> + A type of operands and returned value. + </member> + </members> + <constants> + <constant name="OP_TYPE_SCALAR" value="0" enum="OpType"> + A scalar type. + </constant> + <constant name="OP_TYPE_VECTOR" value="1" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType"> + A vector type. [code]edge[/code] port is using a scalar type. + </constant> + <constant name="OP_TYPE_MAX" value="3" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeSwitch.xml b/doc/classes/VisualShaderNodeSwitch.xml index 9f8a12c0fd..3961070a74 100644 --- a/doc/classes/VisualShaderNodeSwitch.xml +++ b/doc/classes/VisualShaderNodeSwitch.xml @@ -1,15 +1,38 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeSwitch" inherits="VisualShaderNode" version="4.0"> <brief_description> - A boolean/vector function for use within the visual shader graph. + A selector function for use within the visual shader graph. </brief_description> <description> - Returns an associated vector if the provided boolean value is [code]true[/code] or [code]false[/code]. + Returns an associated value of the [code]op_type[/code] type if the provided boolean value is [code]true[/code] or [code]false[/code]. </description> <tutorials> </tutorials> <methods> </methods> + <members> + <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeSwitch.OpType" default="0"> + A type of operands and returned value. + </member> + </members> <constants> + <constant name="OP_TYPE_FLOAT" value="0" enum="OpType"> + A floating-point scalar. + </constant> + <constant name="OP_TYPE_INT" value="1" enum="OpType"> + An integer scalar. + </constant> + <constant name="OP_TYPE_VECTOR" value="2" enum="OpType"> + A vector type. + </constant> + <constant name="OP_TYPE_BOOLEAN" value="3" enum="OpType"> + A boolean type. + </constant> + <constant name="OP_TYPE_TRANSFORM" value="4" enum="OpType"> + A transform type. + </constant> + <constant name="OP_TYPE_MAX" value="5" enum="OpType"> + Represents the size of the [enum OpType] enum. + </constant> </constants> </class> diff --git a/doc/classes/VisualShaderNodeVectorClamp.xml b/doc/classes/VisualShaderNodeVectorClamp.xml deleted file mode 100644 index 567fed8a41..0000000000 --- a/doc/classes/VisualShaderNodeVectorClamp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorClamp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Clamps a vector value within the visual shader graph. - </brief_description> - <description> - Constrains a value to lie between [code]min[/code] and [code]max[/code] values. The operation is performed on each component of the vector individually. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorInterp.xml b/doc/classes/VisualShaderNodeVectorInterp.xml deleted file mode 100644 index b63d34b742..0000000000 --- a/doc/classes/VisualShaderNodeVectorInterp.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorInterp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Linearly interpolates between two vectors within the visual shader graph. - </brief_description> - <description> - Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]weight[/code] is a [Vector3] with weights for each component. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml deleted file mode 100644 index 791a9e6be1..0000000000 --- a/doc/classes/VisualShaderNodeVectorScalarMix.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Linearly interpolates between two vectors using a scalar. For use within the visual shader graph. - </brief_description> - <description> - Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]a[/code] and [code]b[/code] are vectors and [code]weight[/code] is a scalar. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml b/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml deleted file mode 100644 index 580abaf5fe..0000000000 --- a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorScalarSmoothStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a vector SmoothStep function using scalar within the visual shader graph. - </brief_description> - <description> - Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a scalar. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorScalarStep.xml b/doc/classes/VisualShaderNodeVectorScalarStep.xml deleted file mode 100644 index d61414f3a8..0000000000 --- a/doc/classes/VisualShaderNodeVectorScalarStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorScalarStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a vector Step function within the visual shader graph. - </brief_description> - <description> - Translates to [code]step(edge, x)[/code] in the shader language. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeVectorSmoothStep.xml b/doc/classes/VisualShaderNodeVectorSmoothStep.xml deleted file mode 100644 index 1b77a3c535..0000000000 --- a/doc/classes/VisualShaderNodeVectorSmoothStep.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeVectorSmoothStep" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Calculates a vector SmoothStep function within the visual shader graph. - </brief_description> - <description> - Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a vector. - Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 72ab18d115..082f247476 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -80,11 +80,11 @@ public: int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; } AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); } uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; } - void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) override {} /* SKY API */ - RID sky_create() override { return RID(); } + RID sky_allocate() override { return RID(); } + void sky_initialize(RID p_rid) override {} void sky_set_radiance_size(RID p_sky, int p_radiance_size) override {} void sky_set_mode(RID p_sky, RS::SkyMode p_samples) override {} void sky_set_material(RID p_sky, RID p_material) override {} @@ -92,8 +92,8 @@ public: /* ENVIRONMENT API */ - RID environment_create() override { return RID(); } - + RID environment_allocate() override { return RID(); } + void environment_initialize(RID p_rid) override {} void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {} void environment_set_sky(RID p_env, RID p_sky) override {} void environment_set_sky_custom_fov(RID p_env, float p_scale) override {} @@ -112,7 +112,7 @@ public: void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {} void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} - void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} + void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {} void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {} @@ -123,11 +123,9 @@ public: void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {} void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {} - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {} + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) override {} void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {} void environment_set_volumetric_fog_filter_active(bool p_enable) override {} - void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) override {} - void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) override {} Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } @@ -135,8 +133,8 @@ public: RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; } int environment_get_canvas_max_layer(RID p_env) const override { return 0; } - RID camera_effects_create() override { return RID(); } - + RID camera_effects_allocate() override { return RID(); } + void camera_effects_initialize(RID p_rid) override {} void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {} void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override {} @@ -177,11 +175,8 @@ public: void gi_probe_set_quality(RS::GIProbeQuality) override {} - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) override {} - void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) override {} + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override {} void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} - void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) override {} - void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) override {} void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} void set_scene_pass(uint64_t p_pass) override {} @@ -212,50 +207,22 @@ public: class RasterizerStorageDummy : public RendererStorage { public: - /* TEXTURE API */ - struct DummyTexture { - int width = 0; - int height = 0; - uint32_t flags = 0; - Image::Format format = Image::Format::FORMAT_MAX; - Ref<Image> image; - String path; - }; - - struct DummySurface { - uint32_t format = 0; - RS::PrimitiveType primitive = RS::PrimitiveType::PRIMITIVE_MAX; - Vector<uint8_t> array; - int vertex_count = 0; - Vector<uint8_t> index_array; - int index_count = 0; - AABB aabb; - Vector<Vector<uint8_t>> blend_shapes; - Vector<AABB> bone_aabbs; - }; - - struct DummyMesh { - Vector<DummySurface> surfaces; - int blend_shape_count = 0; - RS::BlendShapeMode blend_shape_mode = RS::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED; - }; - - mutable RID_PtrOwner<DummyTexture> texture_owner; - mutable RID_PtrOwner<DummyMesh> mesh_owner; - - RID texture_2d_create(const Ref<Image> &p_image) override { return RID(); } - RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override { return RID(); } - RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override { return RID(); } - RID texture_proxy_create(RID p_base) override { return RID(); } + bool can_create_resources_async() const override { return false; } + /* TEXTURE API */ + RID texture_allocate() override { return RID(); } + void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override {} + void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override {} void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {} void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {} + void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override {} void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {} + void texture_proxy_initialize(RID p_texture, RID p_base) override {} void texture_proxy_update(RID p_proxy, RID p_base) override {} - RID texture_2d_placeholder_create() override { return RID(); } - RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) override { return RID(); } - RID texture_3d_placeholder_create() override { return RID(); } + void texture_2d_placeholder_initialize(RID p_texture) override {} + void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override {} + void texture_3d_placeholder_initialize(RID p_texture) override {} Ref<Image> texture_2d_get(RID p_texture) const override { return Ref<Image>(); } Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override { return Ref<Image>(); } @@ -263,10 +230,6 @@ public: void texture_replace(RID p_texture, RID p_by_texture) override {} void texture_set_size_override(RID p_texture, int p_width, int p_height) override {} -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - void texture_bind(RID p_texture, uint32_t p_texture_no) = 0; -#endif void texture_set_path(RID p_texture, const String &p_path) override {} String texture_get_path(RID p_texture) const override { return String(); } @@ -284,113 +247,18 @@ public: /* CANVAS TEXTURE API */ - RID canvas_texture_create() override { return RID(); } + RID canvas_texture_allocate() override { return RID(); } + void canvas_texture_initialize(RID p_rid) override {} void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override {} void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override {} void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {} void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {} -#if 0 - RID texture_create() override { - DummyTexture *texture = memnew(DummyTexture); - ERR_FAIL_COND_V(!texture, RID()); - return texture_owner.make_rid(texture); - } - - void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, RenderingServer::TextureType p_type = RS::TEXTURE_TYPE_2D, uint32_t p_flags = RS::TEXTURE_FLAGS_DEFAULT) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->width = p_width; - t->height = p_height; - t->flags = p_flags; - t->format = p_format; - t->image = Ref<Image>(memnew(Image)); - t->image->create(p_width, p_height, false, p_format); - } - void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_level) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->width = p_image->get_width(); - t->height = p_image->get_height(); - t->format = p_image->get_format(); - t->image->create(t->width, t->height, false, t->format, p_image->get_data()); - } - - void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_level) override { - DummyTexture *t = texture_owner.getornull(p_texture); - - ERR_FAIL_COND(!t); - ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object."); - ERR_FAIL_COND(t->format != p_image->get_format()); - ERR_FAIL_COND(src_w <= 0 || src_h <= 0); - ERR_FAIL_COND(src_x < 0 || src_y < 0 || src_x + src_w > p_image->get_width() || src_y + src_h > p_image->get_height()); - ERR_FAIL_COND(dst_x < 0 || dst_y < 0 || dst_x + src_w > t->width || dst_y + src_h > t->height); - - t->image->blit_rect(p_image, Rect2(src_x, src_y, src_w, src_h), Vector2(dst_x, dst_y)); - } - - Ref<Image> texture_get_data(RID p_texture, int p_level) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, Ref<Image>()); - return t->image; - } - void texture_set_flags(RID p_texture, uint32_t p_flags) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->flags = p_flags; - } - uint32_t texture_get_flags(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, 0); - return t->flags; - } - Image::Format texture_get_format(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, Image::FORMAT_RGB8); - return t->format; - } - - RenderingServer::TextureType texture_get_type(RID p_texture) const override { return RS::TEXTURE_TYPE_2D; } - uint32_t texture_get_texid(RID p_texture) const override { return 0; } - uint32_t texture_get_width(RID p_texture) const override { return 0; } - uint32_t texture_get_height(RID p_texture) const override { return 0; } - uint32_t texture_get_depth(RID p_texture) const override { return 0; } - void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) override {} - void texture_bind(RID p_texture, uint32_t p_texture_no) override {} - - void texture_set_path(RID p_texture, const String &p_path) override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND(!t); - t->path = p_path; - } - String texture_get_path(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); - ERR_FAIL_COND_V(!t, String()); - return t->path; - } - - void texture_set_shrink_all_x2_on_set_data(bool p_enable) override {} - - void texture_debug_usage(List<RS::TextureInfo> *r_info) override {} - - RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const override { return RID(); } - - void texture_set_detect_3d_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {} - void texture_set_detect_srgb_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {} - void texture_set_detect_normal_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {} - - void textures_keep_original(bool p_enable) override {} - - void texture_set_proxy(RID p_proxy, RID p_base) override {} - Size2 texture_size_with_proxy(RID p_texture) const override { return Size2(); } - void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {} -#endif - /* SHADER API */ - RID shader_create() override { return RID(); } - + RID shader_allocate() override { return RID(); } + void shader_initialize(RID p_rid) override {} void shader_set_code(RID p_shader, const String &p_code) override {} String shader_get_code(RID p_shader) const override { return ""; } void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} @@ -403,8 +271,8 @@ public: /* COMMON MATERIAL API */ - RID material_create() override { return RID(); } - + RID material_allocate() override { return RID(); } + void material_initialize(RID p_rid) override {} void material_set_render_priority(RID p_material, int priority) override {} void material_set_shader(RID p_shader_material, RID p_shader) override {} @@ -420,14 +288,8 @@ public: /* MESH API */ - RID mesh_create() override { - DummyMesh *mesh = memnew(DummyMesh); - ERR_FAIL_COND_V(!mesh, RID()); - mesh->blend_shape_count = 0; - mesh->blend_shape_mode = RS::BLEND_SHAPE_MODE_NORMALIZED; - return mesh_owner.make_rid(mesh); - } - + RID mesh_allocate() override { return RID(); } + void mesh_initialize(RID p_rid) override {} void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {} bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; } RID mesh_instance_create(RID p_base) override { return RID(); } @@ -440,139 +302,31 @@ public: void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override {} -#if 0 - void mesh_add_surface(RID p_mesh, uint32_t p_format, RS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - - m->surfaces.push_back(DummySurface()); - DummySurface *s = &m->surfaces.write[m->surfaces.size() - 1]; - s->format = p_format; - s->primitive = p_primitive; - s->array = p_array; - s->vertex_count = p_vertex_count; - s->index_array = p_index_array; - s->index_count = p_index_count; - s->aabb = p_aabb; - s->blend_shapes = p_blend_shapes; - s->bone_aabbs = p_bone_aabbs; - } - - void mesh_set_blend_shape_count(RID p_mesh, int p_amount) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - m->blend_shape_count = p_amount; - } -#endif - - int mesh_get_blend_shape_count(RID p_mesh) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - return m->blend_shape_count; - } + int mesh_get_blend_shape_count(RID p_mesh) const override { return 0; } - void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - m->blend_shape_mode = p_mode; - } - RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, RS::BLEND_SHAPE_MODE_NORMALIZED); - return m->blend_shape_mode; - } + void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {} + RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { return RS::BLEND_SHAPE_MODE_NORMALIZED; } void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {} void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {} RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); } -#if 0 - int mesh_surface_get_array_len(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - - return m->surfaces[p_surface].vertex_count; - } - int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - - return m->surfaces[p_surface].index_count; - } - - Vector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<uint8_t>()); - - return m->surfaces[p_surface].array; - } - Vector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<uint8_t>()); - - return m->surfaces[p_surface].index_array; - } - - uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - - return m->surfaces[p_surface].format; - } - RS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, RS::PRIMITIVE_POINTS); - - return m->surfaces[p_surface].primitive; - } - - AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, AABB()); - - return m->surfaces[p_surface].aabb; - } - Vector<Vector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<Vector<uint8_t> >()); - - return m->surfaces[p_surface].blend_shapes; - } - Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, Vector<AABB>()); - - return m->surfaces[p_surface].bone_aabbs; - } - - void mesh_remove_surface(RID p_mesh, int p_index) override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND(!m); - ERR_FAIL_COND(p_index >= m->surfaces.size()); - - m->surfaces.remove(p_index); - } -#endif - RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override { return RS::SurfaceData(); } - int mesh_get_surface_count(RID p_mesh) const override { - DummyMesh *m = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!m, 0); - return m->surfaces.size(); - } + int mesh_get_surface_count(RID p_mesh) const override { return 0; } void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override {} AABB mesh_get_custom_aabb(RID p_mesh) const override { return AABB(); } AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); } + void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override {} void mesh_clear(RID p_mesh) override {} /* MULTIMESH API */ - RID multimesh_create() override { return RID(); } - - void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {} + RID multimesh_allocate() override { return RID(); } + void multimesh_initialize(RID p_rid) override {} + void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {} int multimesh_get_instance_count(RID p_multimesh) const override { return 0; } void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override {} @@ -596,7 +350,8 @@ public: /* IMMEDIATE API */ - RID immediate_create() override { return RID(); } + RID immediate_allocate() override { return RID(); } + void immediate_initialize(RID p_rid) override {} void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) override {} void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) override {} void immediate_normal(RID p_immediate, const Vector3 &p_normal) override {} @@ -612,8 +367,9 @@ public: /* SKELETON API */ - RID skeleton_create() override { return RID(); } - void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {} + RID skeleton_allocate() override { return RID(); } + void skeleton_initialize(RID p_rid) override {} + void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {} void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override {} int skeleton_get_bone_count(RID p_skeleton) const override { return 0; } void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) override {} @@ -623,7 +379,14 @@ public: /* Light API */ - RID light_create(RS::LightType p_type) override { return RID(); } + RID directional_light_allocate() override { return RID(); } + void directional_light_initialize(RID p_rid) override {} + RID omni_light_allocate() override { return RID(); } + void omni_light_initialize(RID p_rid) override {} + RID spot_light_allocate() override { return RID(); } + void spot_light_initialize(RID p_rid) override {} + RID reflection_probe_allocate() override { return RID(); } + void reflection_probe_initialize(RID p_rid) override {} void light_set_color(RID p_light, const Color &p_color) override {} void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {} @@ -661,8 +424,6 @@ public: /* PROBE API */ - RID reflection_probe_create() override { return RID(); } - void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override {} void reflection_probe_set_intensity(RID p_probe, float p_intensity) override {} void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override {} @@ -690,7 +451,8 @@ public: /* DECAL API */ - RID decal_create() override { return RID(); } + RID decal_allocate() override { return RID(); } + void decal_initialize(RID p_rid) override {} void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {} void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {} void decal_set_emission_energy(RID p_decal, float p_energy) override {} @@ -705,9 +467,9 @@ public: /* GI PROBE API */ - RID gi_probe_create() override { return RID(); } - - void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {} + RID gi_probe_allocate() override { return RID(); } + void gi_probe_initialize(RID p_rid) override {} + void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {} AABB gi_probe_get_bounds(RID p_gi_probe) const override { return AABB(); } Vector3i gi_probe_get_octree_size(RID p_gi_probe) const override { return Vector3i(); } @@ -751,72 +513,8 @@ public: uint32_t gi_probe_get_version(RID p_gi_probe) override { return 0; } /* LIGHTMAP CAPTURE */ -#if 0 - struct Instantiable { - SelfList<RendererSceneRender::GeometryInstance>::List instance_list; - - _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) override { - SelfList<RendererSceneRender::GeometryInstance> *instances = instance_list.first(); - while (instances) override { - //instances->self()->base_changed(p_aabb, p_materials); - instances = instances->next(); - } - } - - _FORCE_INLINE_ void instance_remove_deps() override { - SelfList<RendererSceneRender::GeometryInstance> *instances = instance_list.first(); - while (instances) override { - SelfList<RendererSceneRender::GeometryInstance> *next = instances->next(); - //instances->self()->base_removed(); - instances = next; - } - } - - Instantiable() override {} - ~Instantiable() override { - } - }; - - struct LightmapCapture : public Instantiable { - Vector<LightmapCaptureOctree> octree; - AABB bounds; - Transform cell_xform; - int cell_subdiv; - float energy; - LightmapCapture() override { - energy = 1.0; - cell_subdiv = 1; - } - }; - - mutable RID_PtrOwner<LightmapCapture> lightmap_capture_data_owner; - void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) override {} - AABB lightmap_capture_get_bounds(RID p_capture) const override { return AABB(); } - void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) override {} - RID lightmap_capture_create() override { - LightmapCapture *capture = memnew(LightmapCapture); - return lightmap_capture_data_owner.make_rid(capture); - } - Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const override { - const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture); - ERR_FAIL_COND_V(!capture, Vector<uint8_t>()); - return Vector<uint8_t>(); - } - void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) override {} - Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const override { return Transform(); } - void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) override {} - int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const override { return 0; } - void lightmap_capture_set_energy(RID p_capture, float p_energy) override {} - float lightmap_capture_get_energy(RID p_capture) const override { return 0.0; } - const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const override { - const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture); - ERR_FAIL_COND_V(!capture, nullptr); - return &capture->octree; - } -#endif - - RID lightmap_create() override { return RID(); } - + RID lightmap_allocate() override { return RID(); } + void lightmap_initialize(RID p_rid) override {} void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {} void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {} void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override {} @@ -833,8 +531,8 @@ public: /* PARTICLES */ - RID particles_create() override { return RID(); } - + RID particles_allocate() override { return RID(); } + void particles_initialize(RID p_rid) override {} void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {} void particles_set_emitting(RID p_particles, bool p_emitting) override {} void particles_set_amount(RID p_particles, int p_amount) override {} @@ -876,7 +574,8 @@ public: /* PARTICLES COLLISION */ - RID particles_collision_create() override { return RID(); } + RID particles_collision_allocate() override { return RID(); } + void particles_collision_initialize(RID p_rid) override {} void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) override {} void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) override {} void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) override {} @@ -935,30 +634,8 @@ public: void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {} Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); } - RS::InstanceType get_base_type(RID p_rid) const override { - if (mesh_owner.owns(p_rid)) { - return RS::INSTANCE_MESH; - } - - return RS::INSTANCE_NONE; - } - - bool free(RID p_rid) override { - if (texture_owner.owns(p_rid)) { - // delete the texture - DummyTexture *texture = texture_owner.getornull(p_rid); - texture_owner.free(p_rid); - memdelete(texture); - } - - if (mesh_owner.owns(p_rid)) { - // delete the mesh - DummyMesh *mesh = mesh_owner.getornull(p_rid); - mesh_owner.free(p_rid); - memdelete(mesh); - } - return true; - } + RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; } + bool free(RID p_rid) override { return true; } bool has_os_feature(const String &p_feature) const override { return false; } diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp index 2484e6d140..f148e42845 100644 --- a/drivers/dummy/texture_loader_dummy.cpp +++ b/drivers/dummy/texture_loader_dummy.cpp @@ -35,7 +35,7 @@ #include <string.h> -RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { unsigned int width = 8; unsigned int height = 8; diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h index 3b71b5824f..00e6b9cc53 100644 --- a/drivers/dummy/texture_loader_dummy.h +++ b/drivers/dummy/texture_loader_dummy.h @@ -36,7 +36,7 @@ class ResourceFormatDummyTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index ef331ec4b6..9584dd3f67 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -74,11 +74,13 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID } else if (texture_buffer_owner.owns(p_buffer)) { if (p_post_barrier & BARRIER_MASK_RASTER) { r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + r_access_mask |= VK_ACCESS_SHADER_READ_BIT; } if (p_post_barrier & BARRIER_MASK_COMPUTE) { r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + r_access_mask |= VK_ACCESS_SHADER_READ_BIT; } - r_access_mask |= VK_ACCESS_SHADER_READ_BIT; + buffer = &texture_buffer_owner.getornull(p_buffer)->buffer; } else if (storage_buffer_owner.owns(p_buffer)) { buffer = storage_buffer_owner.getornull(p_buffer); @@ -1627,6 +1629,9 @@ void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mas mem_barrier.srcAccessMask = p_src_access; mem_barrier.dstAccessMask = p_dst_sccess; + if (p_src_stage_mask == 0 || p_dst_stage_mask == 0) { + return; //no barrier, since this is invalid + } vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, p_src_stage_mask, p_dst_stage_mask, 0, 1, &mem_barrier, 0, nullptr, 0, nullptr); } @@ -2477,6 +2482,10 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; } + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; @@ -2496,6 +2505,13 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } + if (texture->used_in_frame != frames_drawn) { + texture->used_in_raster = false; + texture->used_in_compute = false; + texture->used_in_frame = frames_drawn; + } + texture->used_in_transfer = true; + return OK; } @@ -2844,6 +2860,10 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; } + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + { //restore src VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -3011,6 +3031,10 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; } + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + { //restore src VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -3143,6 +3167,10 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; } + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; @@ -3163,6 +3191,13 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); } + if (src_tex->used_in_frame != frames_drawn) { + src_tex->used_in_raster = false; + src_tex->used_in_compute = false; + src_tex->used_in_frame = frames_drawn; + } + src_tex->used_in_transfer = true; + return OK; } @@ -3289,6 +3324,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF dependency_from_external.srcStageMask |= reading_stages; } } break; + case INITIAL_ACTION_CLEAR_REGION_CONTINUE: case INITIAL_ACTION_CONTINUE: { if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; @@ -3296,7 +3332,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; //don't care what is there + description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; } else { description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -3425,8 +3461,13 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF render_pass_create_info.pAttachments = attachments.ptr(); render_pass_create_info.subpassCount = 1; render_pass_create_info.pSubpasses = &subpass; - render_pass_create_info.dependencyCount = 2; - render_pass_create_info.pDependencies = dependencies; + // Commenting this because it seems it just avoids raster and compute to work at the same time. + // Other barriers seem to be protecting the render pass fine. + // render_pass_create_info.dependencyCount = 2; + // render_pass_create_info.pDependencies = dependencies; + + render_pass_create_info.dependencyCount = 0; + render_pass_create_info.pDependencies = nullptr; VkRenderPass render_pass; VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass); @@ -4108,6 +4149,8 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages bool is_compute = false; + uint32_t compute_local_size[3] = { 0, 0, 0 }; + for (int i = 0; i < p_stages.size(); i++) { if (p_stages[i].shader_stage == SHADER_STAGE_COMPUTE) { is_compute = true; @@ -4124,6 +4167,11 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_stages[i].shader_stage]) + "' failed parsing shader."); + if (is_compute) { + compute_local_size[0] = module.entry_points->local_size.x; + compute_local_size[1] = module.entry_points->local_size.y; + compute_local_size[2] = module.entry_points->local_size.z; + } uint32_t binding_count = 0; result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), @@ -4328,6 +4376,7 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages } } } + uint32_t pc_count = 0; result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), @@ -4376,6 +4425,9 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages shader.fragment_outputs = fragment_outputs; shader.push_constant = push_constant; shader.is_compute = is_compute; + shader.compute_local_size[0] = compute_local_size[0]; + shader.compute_local_size[1] = compute_local_size[1]; + shader.compute_local_size[2] = compute_local_size[2]; String error_text; @@ -5216,7 +5268,14 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, true); + if (dst_stage_mask == 0) { + dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + if (p_post_barrier != RD::BARRIER_MASK_NO_BARRIER) { + _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, true); + } + #endif return err; } @@ -5255,7 +5314,12 @@ Error RenderingDeviceVulkan::buffer_clear(RID p_buffer, uint32_t p_offset, uint3 #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_post_barrier); + if (dst_stage_mask == 0) { + dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, dst_stage_mask); + #endif return OK; } @@ -5710,6 +5774,9 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) { pipeline.pipeline_layout = shader->pipeline_layout; pipeline.shader = p_shader; pipeline.push_constant_size = shader->push_constant.push_constant_size; + pipeline.local_group_size[0] = shader->compute_local_size[0]; + pipeline.local_group_size[1] = shader->compute_local_size[1]; + pipeline.local_group_size[2] = shader->compute_local_size[2]; //create ID to associate with this pipeline RID id = compute_pipeline_owner.make_rid(pipeline); @@ -6019,7 +6086,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); - ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); + ERR_FAIL_COND_V_MSG(compute_list != nullptr && !compute_list->state.allow_draw_overlap, INVALID_ID, "Only one draw/compute list can be active at the same time."); Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer); ERR_FAIL_COND_V(!framebuffer, INVALID_ID); @@ -6040,7 +6107,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu viewport_offset = regioni.position; viewport_size = regioni.size; - + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_CONTINUE; + } if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_color = true; p_initial_color_action = INITIAL_ACTION_KEEP; @@ -6388,6 +6462,19 @@ void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_ dl->state.sets[p_index].uniform_set_format = uniform_set->format; dl->state.sets[p_index].uniform_set = p_uniform_set; + uint32_t mst_count = uniform_set->mutable_storage_textures.size(); + if (mst_count) { + Texture **mst_textures = const_cast<UniformSet *>(uniform_set)->mutable_storage_textures.ptrw(); + for (uint32_t i = 0; i < mst_count; i++) { + if (mst_textures[i]->used_in_frame != frames_drawn) { + mst_textures[i]->used_in_frame = frames_drawn; + mst_textures[i]->used_in_transfer = false; + mst_textures[i]->used_in_compute = false; + } + mst_textures[i]->used_in_raster = true; + } + } + #ifdef DEBUG_ENABLED { //validate that textures bound are not attached as framebuffer bindings uint32_t attachable_count = uniform_set->attachable_textures.size(); @@ -6673,23 +6760,43 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; } if (p_post_barrier & BARRIER_MASK_RASTER) { - barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; - access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT /*| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT*/; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT /*| VK_ACCESS_INDIRECT_COMMAND_READ_BIT*/; } if (p_post_barrier & BARRIER_MASK_TRANSFER) { barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; } + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + draw_list_bound_textures.clear(); - for (int i = 0; i < draw_list_storage_textures.size(); i++) { + VkImageMemoryBarrier *image_barriers = nullptr; + + uint32_t image_barrier_count = draw_list_storage_textures.size(); + + if (image_barrier_count) { + image_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * draw_list_storage_textures.size()); + } + + uint32_t src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + uint32_t src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + if (image_barrier_count) { + src_stage |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + src_access |= VK_ACCESS_SHADER_WRITE_BIT; + } + + for (uint32_t i = 0; i < image_barrier_count; i++) { Texture *texture = texture_owner.getornull(draw_list_storage_textures[i]); - VkImageMemoryBarrier image_memory_barrier; + VkImageMemoryBarrier &image_memory_barrier = image_barriers[i]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; - image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.srcAccessMask = src_access; image_memory_barrier.dstAccessMask = access_flags; image_memory_barrier.oldLayout = texture->layout; image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -6703,8 +6810,6 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer; image_memory_barrier.subresourceRange.layerCount = texture->layers; - vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } @@ -6717,7 +6822,17 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, barrier_flags, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, access_flags, true); + + VkMemoryBarrier mem_barrier; + mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + mem_barrier.pNext = nullptr; + mem_barrier.srcAccessMask = src_access; + mem_barrier.dstAccessMask = access_flags; + + if (image_barrier_count > 0 || p_post_barrier != BARRIER_MASK_NO_BARRIER) { + vkCmdPipelineBarrier(frames[frame].draw_command_buffer, src_stage, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers); + } + #endif } @@ -6725,12 +6840,13 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { /**** COMPUTE LISTS ****/ /***********************/ -RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin() { - ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); +RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin(bool p_allow_draw_overlap) { + ERR_FAIL_COND_V_MSG(!p_allow_draw_overlap && draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); compute_list = memnew(ComputeList); compute_list->command_buffer = frames[frame].draw_command_buffer; + compute_list->state.allow_draw_overlap = p_allow_draw_overlap; return ID_TYPE_COMPUTE_LIST; } @@ -6787,6 +6903,9 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l } cl->state.pipeline_shader = pipeline->shader; + cl->state.local_group_size[0] = pipeline->local_group_size[0]; + cl->state.local_group_size[1] = pipeline->local_group_size[1]; + cl->state.local_group_size[2] = pipeline->local_group_size[2]; } #ifdef DEBUG_ENABLED @@ -6824,11 +6943,24 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, cl->state.sets[p_index].uniform_set = p_uniform_set; uint32_t textures_to_sampled_count = uniform_set->mutable_sampled_textures.size(); + uint32_t textures_to_storage_count = uniform_set->mutable_storage_textures.size(); + Texture **textures_to_sampled = uniform_set->mutable_sampled_textures.ptrw(); + VkImageMemoryBarrier *texture_barriers = nullptr; + + if (textures_to_sampled_count + textures_to_storage_count) { + texture_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * (textures_to_sampled_count + textures_to_storage_count)); + } + uint32_t texture_barrier_count = 0; + + uint32_t src_stage_flags = 0; + for (uint32_t i = 0; i < textures_to_sampled_count; i++) { if (textures_to_sampled[i]->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - VkImageMemoryBarrier image_memory_barrier; + src_stage_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + + VkImageMemoryBarrier &image_memory_barrier = texture_barriers[texture_barrier_count++]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; @@ -6845,23 +6977,55 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_sampled[i]->base_layer; image_memory_barrier.subresourceRange.layerCount = textures_to_sampled[i]->layers; - vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - textures_to_sampled[i]->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; cl->state.textures_to_sampled_layout.erase(textures_to_sampled[i]); } + + if (textures_to_sampled[i]->used_in_frame != frames_drawn) { + textures_to_sampled[i]->used_in_frame = frames_drawn; + textures_to_sampled[i]->used_in_transfer = false; + textures_to_sampled[i]->used_in_raster = false; + } + textures_to_sampled[i]->used_in_compute = true; } - uint32_t textures_to_storage_count = uniform_set->mutable_storage_textures.size(); Texture **textures_to_storage = uniform_set->mutable_storage_textures.ptrw(); for (uint32_t i = 0; i < textures_to_storage_count; i++) { if (textures_to_storage[i]->layout != VK_IMAGE_LAYOUT_GENERAL) { - VkImageMemoryBarrier image_memory_barrier; + uint32_t src_access_flags = 0; + + if (textures_to_storage[i]->used_in_frame == frames_drawn) { + if (textures_to_storage[i]->used_in_compute) { + src_stage_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + src_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (textures_to_storage[i]->used_in_raster) { + src_stage_flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; + src_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + } + if (textures_to_storage[i]->used_in_transfer) { + src_stage_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT; + src_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; + } + + textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_raster = false; + textures_to_storage[i]->used_in_compute = false; + + } else { + src_access_flags = 0; + textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_raster = false; + textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_frame = frames_drawn; + } + + VkImageMemoryBarrier &image_memory_barrier = texture_barriers[texture_barrier_count++]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; - image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.srcAccessMask = src_access_flags; image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; image_memory_barrier.oldLayout = textures_to_storage[i]->layout; image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -6875,14 +7039,20 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_storage[i]->base_layer; image_memory_barrier.subresourceRange.layerCount = textures_to_storage[i]->layers; - vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - textures_to_storage[i]->layout = VK_IMAGE_LAYOUT_GENERAL; cl->state.textures_to_sampled_layout.insert(textures_to_storage[i]); //needs to go back to sampled layout afterwards } } + if (texture_barrier_count) { + if (src_stage_flags == 0) { + src_stage_flags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + } + + vkCmdPipelineBarrier(cl->command_buffer, src_stage_flags, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, texture_barrier_count, texture_barriers); + } + #if 0 { //validate that textures bound are not attached as framebuffer bindings uint32_t attachable_count = uniform_set->attachable_textures.size(); @@ -6976,6 +7146,27 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t vkCmdDispatch(cl->command_buffer, p_x_groups, p_y_groups, p_z_groups); } +void RenderingDeviceVulkan::compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads) { + ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); + ERR_FAIL_COND(!compute_list); + + ComputeList *cl = compute_list; + +#ifdef DEBUG_ENABLED + + ERR_FAIL_COND_MSG(!cl->validation.pipeline_active, "No compute pipeline was set before attempting to draw."); + + if (cl->validation.pipeline_push_constant_size > 0) { + //using push constants, check that they were supplied + ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied, + "The shader in this pipeline requires a push constant to be set before drawing, but it's not present."); + } + +#endif + + compute_list_dispatch(p_list, (p_x_threads - 1) / cl->state.local_group_size[0] + 1, (p_y_threads - 1) / cl->state.local_group_size[1] + 1, (p_z_threads - 1) / cl->state.local_group_size[2] + 1); +} + void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -7047,7 +7238,7 @@ void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) { uint32_t access_flags = 0; if (p_post_barrier & BARRIER_MASK_COMPUTE) { barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; } if (p_post_barrier & BARRIER_MASK_RASTER) { barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; @@ -7058,8 +7249,22 @@ void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) { access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; } + if (barrier_flags == 0) { + barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + + VkImageMemoryBarrier *image_barriers = nullptr; + + uint32_t image_barrier_count = compute_list->state.textures_to_sampled_layout.size(); + + if (image_barrier_count) { + image_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * image_barrier_count); + } + + uint32_t barrier_idx = 0; + for (Set<Texture *>::Element *E = compute_list->state.textures_to_sampled_layout.front(); E; E = E->next()) { - VkImageMemoryBarrier image_memory_barrier; + VkImageMemoryBarrier &image_memory_barrier = image_barriers[barrier_idx++]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; @@ -7076,19 +7281,33 @@ void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) { image_memory_barrier.subresourceRange.baseArrayLayer = E->get()->base_layer; image_memory_barrier.subresourceRange.layerCount = E->get()->layers; - // TODO: Look at the usages in the compute list and determine tighter dst stage and access masks based on some "final" usage equivalent - vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); - E->get()->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + if (E->get()->used_in_frame != frames_drawn) { + E->get()->used_in_transfer = false; + E->get()->used_in_raster = false; + E->get()->used_in_compute = false; + E->get()->used_in_frame = frames_drawn; + } } - memdelete(compute_list); - compute_list = nullptr; #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, barrier_flags, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT, true); + VkMemoryBarrier mem_barrier; + mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + mem_barrier.pNext = nullptr; + mem_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + mem_barrier.dstAccessMask = access_flags; + + if (image_barrier_count > 0 || p_post_barrier != BARRIER_MASK_NO_BARRIER) { + vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers); + } + #endif + + memdelete(compute_list); + compute_list = nullptr; } void RenderingDeviceVulkan::barrier(uint32_t p_from, uint32_t p_to) { @@ -7107,11 +7326,15 @@ void RenderingDeviceVulkan::barrier(uint32_t p_from, uint32_t p_to) { src_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT; } + if (p_from == 0) { + src_barrier_flags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + } + uint32_t dst_barrier_flags = 0; uint32_t dst_access_flags = 0; if (p_to & BARRIER_MASK_COMPUTE) { dst_barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - dst_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + dst_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; } if (p_to & BARRIER_MASK_RASTER) { dst_barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; @@ -7122,6 +7345,10 @@ void RenderingDeviceVulkan::barrier(uint32_t p_from, uint32_t p_to) { dst_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; } + if (p_to == 0) { + dst_barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + _memory_barrier(src_barrier_flags, dst_barrier_flags, src_access_flags, dst_access_flags, true); } @@ -7325,6 +7552,16 @@ void RenderingDeviceVulkan::draw_command_end_label() { context->command_end_label(frames[frame].draw_command_buffer); } +String RenderingDeviceVulkan::get_device_vendor_name() const { + return context->get_device_vendor_name(); +} +String RenderingDeviceVulkan::get_device_name() const { + return context->get_device_name(); +} +String RenderingDeviceVulkan::get_device_pipeline_cache_uuid() const { + return context->get_device_pipeline_cache_uuid(); +} + void RenderingDeviceVulkan::_finalize_command_bufers() { if (draw_list) { ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); @@ -7377,6 +7614,7 @@ void RenderingDeviceVulkan::_begin_frame() { if (frames[frame].timestamp_count) { vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); + vkCmdResetQueryPool(frames[frame].setup_command_buffer, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count); SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); } diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 4bea17e4a1..a2527d5c33 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -141,6 +141,11 @@ class RenderingDeviceVulkan : public RenderingDevice { VkImageLayout layout; + uint64_t used_in_frame = 0; + bool used_in_transfer = false; + bool used_in_raster = false; + bool used_in_compute = false; + uint32_t read_aspect_mask = 0; uint32_t barrier_aspect_mask = 0; bool bound = false; //bound to framebffer @@ -528,6 +533,8 @@ class RenderingDeviceVulkan : public RenderingDevice { PushConstant push_constant; + uint32_t compute_local_size[3] = { 0, 0, 0 }; + bool is_compute = false; int max_output = 0; Vector<Set> sets; @@ -686,6 +693,7 @@ class RenderingDeviceVulkan : public RenderingDevice { VkPipeline pipeline = VK_NULL_HANDLE; uint32_t push_constant_size = 0; uint32_t push_constant_stages = 0; + uint32_t local_group_size[3] = { 0, 0, 0 }; }; RID_Owner<ComputePipeline, true> compute_pipeline_owner; @@ -808,8 +816,10 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t set_count = 0; RID pipeline; RID pipeline_shader; + uint32_t local_group_size[3] = { 0, 0, 0 }; VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; uint32_t pipeline_push_constant_stages = 0; + bool allow_draw_overlap; } state; #ifdef DEBUG_ENABLED @@ -1028,13 +1038,14 @@ public: /**** COMPUTE LISTS ****/ /***********************/ - virtual ComputeListID compute_list_begin(); + virtual ComputeListID compute_list_begin(bool p_allow_draw_overlap = false); virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline); virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index); virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size); virtual void compute_list_add_barrier(ComputeListID p_list); virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups); + virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads); virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset); virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL); @@ -1085,6 +1096,10 @@ public: virtual void draw_command_insert_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)); virtual void draw_command_end_label(); + virtual String get_device_vendor_name() const; + virtual String get_device_name() const; + virtual String get_device_pipeline_cache_uuid() const; + RenderingDeviceVulkan(); ~RenderingDeviceVulkan(); }; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 1a631f4a2c..c564cee757 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -331,7 +331,7 @@ Error VulkanContext::_create_physical_device() { * function to register the final callback. */ VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info; - if (use_validation_layers) { + if (enabled_debug_utils) { // VK_EXT_debug_utils style dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; dbg_messenger_create_info.pNext = nullptr; @@ -380,7 +380,8 @@ Error VulkanContext::_create_physical_device() { ERR_FAIL_V(ERR_CANT_CREATE); } /* for now, just grab the first physical device */ - gpu = physical_devices[0]; + uint32_t device_index = 0; + gpu = physical_devices[device_index]; free(physical_devices); /* Look for device extensions */ @@ -389,6 +390,40 @@ Error VulkanContext::_create_physical_device() { enabled_extension_count = 0; memset(extension_names, 0, sizeof(extension_names)); + /* Get identifier properties */ + vkGetPhysicalDeviceProperties(gpu, &gpu_props); + + static const struct { + uint32_t id; + const char *name; + } vendor_names[] = { + { 0x1002, "AMD" }, + { 0x1010, "ImgTec" }, + { 0x10DE, "NVIDIA" }, + { 0x13B5, "ARM" }, + { 0x5143, "Qualcomm" }, + { 0x8086, "INTEL" }, + { 0, nullptr }, + }; + device_name = gpu_props.deviceName; + pipeline_cache_id = String::hex_encode_buffer(gpu_props.pipelineCacheUUID, VK_UUID_SIZE); + pipeline_cache_id += "-driver-" + itos(gpu_props.driverVersion); + { + device_vendor = "Unknown"; + uint32_t vendor_idx = 0; + while (vendor_names[vendor_idx].name != nullptr) { + if (gpu_props.vendorID == vendor_names[vendor_idx].id) { + device_vendor = vendor_names[vendor_idx].name; + break; + } + vendor_idx++; + } + } +#ifdef DEBUG_ENABLED + print_line("Using Vulkan Device #" + itos(device_index) + ": " + device_vendor + " - " + device_name); +#endif + device_api_version = gpu_props.apiVersion; + err = vkEnumerateDeviceExtensionProperties(gpu, nullptr, &device_extension_count, nullptr); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); @@ -498,7 +533,6 @@ Error VulkanContext::_create_physical_device() { break; } } - vkGetPhysicalDeviceProperties(gpu, &gpu_props); /* Call with NULL data to get count */ vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr); @@ -565,6 +599,7 @@ Error VulkanContext::_create_device() { } err = vkCreateDevice(gpu, &sdevice, nullptr, &device); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); + return OK; } @@ -1590,10 +1625,12 @@ void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String if (!enabled_debug_utils) { return; } + + CharString cs = p_label_name.utf8().get_data(); VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; - label.pLabelName = p_label_name.utf8().get_data(); + label.pLabelName = cs.get_data(); label.color[0] = p_color[0]; label.color[1] = p_color[1]; label.color[2] = p_color[2]; @@ -1605,10 +1642,11 @@ void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, Strin if (!enabled_debug_utils) { return; } + CharString cs = p_label_name.utf8().get_data(); VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; - label.pLabelName = p_label_name.utf8().get_data(); + label.pLabelName = cs.get_data(); label.color[0] = p_color[0]; label.color[1] = p_color[1]; label.color[2] = p_color[2]; @@ -1627,16 +1665,26 @@ void VulkanContext::set_object_name(VkObjectType p_object_type, uint64_t p_objec if (!enabled_debug_utils) { return; } + CharString obj_data = p_object_name.utf8(); VkDebugUtilsObjectNameInfoEXT name_info; name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; name_info.pNext = nullptr; name_info.objectType = p_object_type; name_info.objectHandle = p_object_handle; - CharString object_name = p_object_name.utf8(); - name_info.pObjectName = object_name.get_data(); + name_info.pObjectName = obj_data.get_data(); SetDebugUtilsObjectNameEXT(device, &name_info); } +String VulkanContext::get_device_vendor_name() const { + return device_vendor; +} +String VulkanContext::get_device_name() const { + return device_name; +} +String VulkanContext::get_device_pipeline_cache_uuid() const { + return pipeline_cache_id; +} + VulkanContext::VulkanContext() { use_validation_layers = Engine::get_singleton()->is_validation_layers_enabled(); diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 5cb762aca8..dc6b0410bc 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -57,6 +57,11 @@ class VulkanContext { bool device_initialized = false; bool inst_initialized = false; + String device_vendor; + String device_name; + String pipeline_cache_id; + uint32_t device_api_version = 0; + bool buffers_prepared = false; // Present queue. @@ -215,6 +220,10 @@ public: void command_end_label(VkCommandBuffer p_command_buffer); void set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name); + String get_device_vendor_name() const; + String get_device_name() const; + String get_device_pipeline_cache_uuid() const; + VulkanContext(); virtual ~VulkanContext(); }; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 5d49290612..934c6b95a4 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -634,7 +634,7 @@ public: bool use_fps = false; void notify_change() { - _change_notify(); + notify_property_list_changed(); } Node *get_root_path() { @@ -643,7 +643,7 @@ public: void set_use_fps(bool p_enable) { use_fps = p_enable; - _change_notify(); + notify_property_list_changed(); } }; @@ -1276,7 +1276,7 @@ public: UndoRedo *undo_redo = nullptr; void notify_change() { - _change_notify(); + notify_property_list_changed(); } Node *get_root_path() { @@ -1285,7 +1285,7 @@ public: void set_use_fps(bool p_enable) { use_fps = p_enable; - _change_notify(); + notify_property_list_changed(); } }; @@ -4283,7 +4283,6 @@ void AnimationTrackEditor::_animation_update() { _update_step_spinbox(); emit_signal("animation_step_changed", animation->get_step()); emit_signal("animation_len_changed", animation->get_length()); - EditorNode::get_singleton()->get_inspector()->refresh(); animation_changing_awaiting_update = false; } diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp index 3daee4587c..09defac354 100644 --- a/editor/array_property_edit.cpp +++ b/editor/array_property_edit.cpp @@ -49,11 +49,7 @@ Variant ArrayPropertyEdit::get_array() const { } void ArrayPropertyEdit::_notif_change() { - _change_notify(); -} - -void ArrayPropertyEdit::_notif_changev(const String &p_v) { - _change_notify(p_v.utf8().get_data()); + notify_property_list_changed(); } void ArrayPropertyEdit::_set_size(int p_size) { @@ -120,7 +116,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { } if (pn == "array/page") { page = p_value; - _change_notify(); + notify_property_list_changed(); return true; } @@ -159,8 +155,6 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { ur->create_action(TTR("Change Array Value")); ur->add_do_method(this, "_set_value", idx, p_value); ur->add_undo_method(this, "_set_value", idx, value); - ur->add_do_method(this, "_notif_changev", p_name); - ur->add_undo_method(this, "_notif_changev", p_name); ur->commit_action(); return true; } @@ -288,7 +282,6 @@ void ArrayPropertyEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_size"), &ArrayPropertyEdit::_set_size); ClassDB::bind_method(D_METHOD("_set_value"), &ArrayPropertyEdit::_set_value); ClassDB::bind_method(D_METHOD("_notif_change"), &ArrayPropertyEdit::_notif_change); - ClassDB::bind_method(D_METHOD("_notif_changev"), &ArrayPropertyEdit::_notif_changev); ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &ArrayPropertyEdit::_dont_undo_redo); } diff --git a/editor/array_property_edit.h b/editor/array_property_edit.h index dd495b57f4..fa3dcbe038 100644 --- a/editor/array_property_edit.h +++ b/editor/array_property_edit.h @@ -47,7 +47,6 @@ class ArrayPropertyEdit : public Reference { Variant::Type default_type; void _notif_change(); - void _notif_changev(const String &p_v); void _set_size(int p_size); void _set_value(int p_idx, const Variant &p_value); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 01fa094d38..0c1fb6fe4d 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -98,7 +98,7 @@ public: } void notify_changed() { - _change_notify(); + notify_property_list_changed(); } ConnectDialogBinds() { diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h index cf2d81cbf1..6648c99c03 100644 --- a/editor/debugger/editor_debugger_inspector.h +++ b/editor/debugger/editor_debugger_inspector.h @@ -58,7 +58,7 @@ public: prop_values.clear(); } - void update() { _change_notify(); } + void update() { notify_property_list_changed(); } EditorDebuggerRemoteObject() {} }; diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 6db3b94aee..ec92edc795 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -129,6 +129,8 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int updating_scene_tree = true; const String last_path = get_selected_path(); const String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter(); + bool filter_changed = filter != last_filter; + TreeItem *scroll_item = nullptr; // Nodes are in a flatten list, depth first. Use a stack of parents, avoid recursion. List<Pair<TreeItem *, int>> parents; @@ -162,11 +164,17 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int if (debugger_id == p_debugger) { // Can use remote id. if (node.id == inspected_object_id) { item->select(0); + if (filter_changed) { + scroll_item = item; + } } } else { // Must use path if (last_path == _get_path(item)) { updating_scene_tree = false; // Force emission of new selection item->select(0); + if (filter_changed) { + scroll_item = item; + } updating_scene_tree = true; } } @@ -183,6 +191,9 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } parent->remove_child(item); memdelete(item); + if (scroll_item == item) { + scroll_item = nullptr; + } if (had_siblings) { break; // Parent must survive. } @@ -199,6 +210,10 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int } } debugger_id = p_debugger; // Needed by hook, could be avoided if every debugger had its own tree + if (scroll_item) { + call_deferred("scroll_to_item", scroll_item); + } + last_filter = filter; updating_scene_tree = false; } diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 8c966dffd5..13193344f1 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -51,6 +51,7 @@ private: Set<ObjectID> unfold_cache; PopupMenu *item_menu = nullptr; EditorFileDialog *file_dialog = nullptr; + String last_filter; String _get_path(TreeItem *p_item); void _scene_tree_folded(Object *p_obj); diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp index 9683003d89..408177e523 100644 --- a/editor/dictionary_property_edit.cpp +++ b/editor/dictionary_property_edit.cpp @@ -32,11 +32,7 @@ #include "editor_node.h" void DictionaryPropertyEdit::_notif_change() { - _change_notify(); -} - -void DictionaryPropertyEdit::_notif_changev(const String &p_v) { - _change_notify(p_v.utf8().get_data()); + notify_property_list_changed(); } void DictionaryPropertyEdit::_set_key(const Variant &p_old_key, const Variant &p_new_key) { @@ -107,7 +103,6 @@ void DictionaryPropertyEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_key"), &DictionaryPropertyEdit::_set_key); ClassDB::bind_method(D_METHOD("_set_value"), &DictionaryPropertyEdit::_set_value); ClassDB::bind_method(D_METHOD("_notif_change"), &DictionaryPropertyEdit::_notif_change); - ClassDB::bind_method(D_METHOD("_notif_changev"), &DictionaryPropertyEdit::_notif_changev); ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &DictionaryPropertyEdit::_dont_undo_redo); } @@ -128,8 +123,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val ur->create_action(TTR("Change Dictionary Key")); ur->add_do_method(this, "_set_key", key, p_value); ur->add_undo_method(this, "_set_key", p_value, key); - ur->add_do_method(this, "_notif_changev", p_name); - ur->add_undo_method(this, "_notif_changev", p_name); ur->commit_action(); return true; @@ -142,8 +135,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val ur->create_action(TTR("Change Dictionary Value")); ur->add_do_method(this, "_set_value", key, p_value); ur->add_undo_method(this, "_set_value", key, value); - ur->add_do_method(this, "_notif_changev", p_name); - ur->add_undo_method(this, "_notif_changev", p_name); ur->commit_action(); return true; diff --git a/editor/dictionary_property_edit.h b/editor/dictionary_property_edit.h index 564bbf205b..e0fd945491 100644 --- a/editor/dictionary_property_edit.h +++ b/editor/dictionary_property_edit.h @@ -40,7 +40,6 @@ class DictionaryPropertyEdit : public Reference { StringName property; void _notif_change(); - void _notif_changev(const String &p_v); void _set_key(const Variant &p_old_key, const Variant &p_new_key); void _set_value(const Variant &p_key, const Variant &p_value); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 2eef4636d6..69a13957e6 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1193,7 +1193,7 @@ void EditorAudioBuses::_load_layout() { void EditorAudioBuses::_load_default_layout() { String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); - Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", true); + Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { EditorNode::get_singleton()->show_warning(vformat(TTR("There is no '%s' file."), layout_path)); return; @@ -1209,7 +1209,7 @@ void EditorAudioBuses::_load_default_layout() { void EditorAudioBuses::_file_dialog_callback(const String &p_string) { if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_OPEN_FILE) { - Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", true); + Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { EditorNode::get_singleton()->show_warning(TTR("Invalid file, not an audio bus layout.")); return; @@ -1330,7 +1330,7 @@ EditorAudioBuses::EditorAudioBuses() { void EditorAudioBuses::open_layout(const String &p_path) { EditorNode::get_singleton()->make_bottom_panel_item_visible(this); - Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", true); + Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { EditorNode::get_singleton()->show_warning(TTR("Invalid file, not an audio bus layout.")); return; diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 336bf26607..18364dc32f 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -500,6 +500,7 @@ int EditorData::add_edited_scene(int p_at_pos) { EditedScene es; es.root = nullptr; es.path = String(); + es.file_modified_time = 0; es.history_current = -1; es.version = 0; es.live_edit_root = NodePath(String("/root")); @@ -656,6 +657,10 @@ void EditorData::set_edited_scene_root(Node *p_root) { p_root->set_filename(edited_scene[current_edited_scene].path); } } + + if (edited_scene[current_edited_scene].path != "") { + edited_scene.write[current_edited_scene].file_modified_time = FileAccess::get_modified_time(edited_scene[current_edited_scene].path); + } } int EditorData::get_edited_scene_count() const { @@ -687,6 +692,21 @@ uint64_t EditorData::get_scene_version(int p_idx) const { return edited_scene[p_idx].version; } +void EditorData::set_scene_modified_time(int p_idx, uint64_t p_time) { + if (p_idx == -1) { + p_idx = current_edited_scene; + } + + ERR_FAIL_INDEX(p_idx, edited_scene.size()); + + edited_scene.write[p_idx].file_modified_time = p_time; +} + +uint64_t EditorData::get_scene_modified_time(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0); + return edited_scene[p_idx].file_modified_time; +} + String EditorData::get_scene_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String()); if (!edited_scene[p_idx].root) { diff --git a/editor/editor_data.h b/editor/editor_data.h index f14a3fb4e0..18b4137162 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -111,6 +111,7 @@ public: struct EditedScene { Node *root = nullptr; String path; + uint64_t file_modified_time = 0; Dictionary editor_states; List<Node *> selection; Vector<EditorHistory::History> history_stored; @@ -190,6 +191,8 @@ public: Ref<Script> get_scene_root_script(int p_idx) const; void set_edited_scene_version(uint64_t version, int p_scene_idx = -1); uint64_t get_scene_version(int p_idx) const; + void set_scene_modified_time(int p_idx, uint64_t p_time); + uint64_t get_scene_modified_time(int p_idx) const; void clear_edited_scenes(); void set_edited_scene_live_edit_root(const NodePath &p_root); NodePath get_edited_scene_live_edit_root(); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index dd3e81c8c0..24256b843e 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1028,6 +1028,10 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) { EditorProgress ep("savepack", TTR("Packing"), 102, true); + // Create the temporary export directory if it doesn't exist. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->make_dir_recursive(EditorSettings::get_singleton()->get_cache_dir()); + String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp"); FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE); ERR_FAIL_COND_V_MSG(!ftmp, ERR_CANT_CREATE, "Cannot create file '" + tmppath + "'."); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index af02fcaf3c..bd00d86ec8 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -277,11 +277,7 @@ void EditorFeatureProfile::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_MAX); } -EditorFeatureProfile::EditorFeatureProfile() { - for (int i = 0; i < FEATURE_MAX; i++) { - features_disabled[i] = false; - } -} +EditorFeatureProfile::EditorFeatureProfile() {} ////////////////////////// diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 9f98795e16..97a2c67c26 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -259,13 +259,17 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { } } } - } - if (E->get().type == Variant::OBJECT) { - RES res = p_object->get(E->get().name); - if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { - resources.insert(res); - _do_object_unfolds(res.ptr(), resources); + if (E->get().type == Variant::OBJECT) { + RES res = p_object->get(E->get().name); + print_line("res: " + String(E->get().name) + " valid " + itos(res.is_valid())); + if (res.is_valid()) { + print_line("path " + res->get_path()); + } + if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { + resources.insert(res); + _do_object_unfolds(res.ptr(), resources); + } } } } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index df330d8685..a7f808f63a 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -81,7 +81,7 @@ Size2 EditorProperty::get_minimum_size() const { } if (bottom_editor != nullptr && bottom_editor->is_visible()) { - ms.height += get_theme_constant("vseparation", "Tree"); + ms.height += get_theme_constant("vseparation"); Size2 bems = bottom_editor->get_combined_minimum_size(); //bems.width += get_constant("item_margin", "Tree"); ms.height += bems.height; @@ -95,6 +95,7 @@ void EditorProperty::emit_changed(const StringName &p_property, const Variant &p Variant args[4] = { p_property, p_value, p_field, p_changing }; const Variant *argptrs[4] = { &args[0], &args[1], &args[2], &args[3] }; + cache[p_property] = p_value; emit_signal("property_changed", (const Variant **)argptrs, 4); } @@ -148,7 +149,7 @@ void EditorProperty::_notification(int p_what) { if (bottom_editor) { int m = 0; //get_constant("item_margin", "Tree"); - bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation", "Tree"), size.width - m, bottom_editor->get_combined_minimum_size().height); + bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation"), size.width - m, bottom_editor->get_combined_minimum_size().height); } if (keying) { @@ -225,11 +226,15 @@ void EditorProperty::_notification(int p_what) { size.height = label_reference->get_size().height; } + Ref<StyleBox> sb; if (selected) { - Ref<StyleBox> sb = get_theme_stylebox("selected", "Tree"); - draw_style_box(sb, Rect2(Vector2(), size)); + sb = get_theme_stylebox("bg_selected"); + } else { + sb = get_theme_stylebox("bg"); } + draw_style_box(sb, Rect2(Vector2(), size)); + if (draw_top_bg && right_child_rect != Rect2()) { draw_rect(right_child_rect, dark_color); } @@ -239,15 +244,15 @@ void EditorProperty::_notification(int p_what) { Color color; if (draw_red) { - color = get_theme_color("error_color", "Editor"); + color = get_theme_color("error_color"); } else { - color = get_theme_color("property_color", "Editor"); + color = get_theme_color("property_color"); } if (label.find(".") != -1) { color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides } - int ofs = 0; + int ofs = get_theme_constant("font_offset"); int text_limit = text_size; if (checkable) { @@ -805,6 +810,28 @@ void EditorProperty::set_bottom_editor(Control *p_control) { bottom_editor = p_control; } +bool EditorProperty::is_cache_valid() const { + if (object) { + for (Map<StringName, Variant>::Element *E = cache.front(); E; E = E->next()) { + bool valid; + Variant value = object->get(E->key(), &valid); + if (!valid || value != E->get()) { + return false; + } + } + } + return true; +} +void EditorProperty::update_cache() { + cache.clear(); + if (object && property != StringName()) { + bool valid; + Variant value = object->get(property, &valid); + if (valid) { + cache[property] = value; + } + } +} Variant EditorProperty::get_drag_data(const Point2 &p_point) { if (property == StringName()) { return Variant(); @@ -1524,6 +1551,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->update_property(); ep->update_reload_status(); ep->set_deletable(deletable_properties); + ep->update_cache(); } } ped->added_editors.clear(); @@ -1982,6 +2010,7 @@ void EditorInspector::update_tree() { } ep->update_property(); ep->update_reload_status(); + ep->update_cache(); if (current_selected && ep->property == current_selected) { ep->select(current_focusable); @@ -2012,6 +2041,7 @@ void EditorInspector::update_property(const String &p_prop) { for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); + E->get()->update_cache(); } } @@ -2027,13 +2057,6 @@ void EditorInspector::_clear() { restart_request_props.clear(); } -void EditorInspector::refresh() { - if (refresh_countdown > 0 || changing) { - return; - } - refresh_countdown = EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval"); -} - Object *EditorInspector::get_edited_object() { return object; } @@ -2044,7 +2067,7 @@ void EditorInspector::edit(Object *p_object) { } if (object) { _clear(); - object->remove_change_receptor(this); + object->disconnect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback)); } object = p_object; @@ -2054,7 +2077,7 @@ void EditorInspector::edit(Object *p_object) { if (scroll_cache.has(object->get_instance_id())) { //if exists, set something else update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accommodated } - object->add_change_receptor(this); + object->connect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback)); update_tree(); } } @@ -2161,17 +2184,30 @@ void EditorInspector::set_use_wide_editors(bool p_enable) { wide_editors = p_enable; } +void EditorInspector::_update_inspector_bg() { + if (sub_inspector) { + int count_subinspectors = 0; + Node *n = get_parent(); + while (n) { + EditorInspector *ei = Object::cast_to<EditorInspector>(n); + if (ei && ei->sub_inspector) { + count_subinspectors++; + } + n = n->get_parent(); + } + count_subinspectors = MIN(15, count_subinspectors); + add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), "Editor")); + } else { + add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); + } +} void EditorInspector::set_sub_inspector(bool p_enable) { sub_inspector = p_enable; if (!is_inside_tree()) { return; } - if (sub_inspector) { - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor")); - } else { - add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); - } + _update_inspector_bg(); } void EditorInspector::set_use_deletable_properties(bool p_enabled) { @@ -2351,6 +2387,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); + E->get()->update_cache(); } } @@ -2394,13 +2431,12 @@ void EditorInspector::_node_removed(Node *p_node) { void EditorInspector::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &EditorInspector::_feature_profile_changed)); + set_process(is_visible_in_tree()); } if (p_what == NOTIFICATION_ENTER_TREE) { - if (sub_inspector) { - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor")); - } else { - add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); + _update_inspector_bg(); + if (!sub_inspector) { get_tree()->connect("node_removed", callable_mp(this, &EditorInspector::_node_removed)); } } @@ -2414,6 +2450,10 @@ void EditorInspector::_notification(int p_what) { edit(nullptr); } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + set_process(is_visible_in_tree()); + } + if (p_what == NOTIFICATION_PROCESS) { if (update_scroll_request >= 0) { get_v_scrollbar()->call_deferred("set_value", update_scroll_request); @@ -2424,10 +2464,14 @@ void EditorInspector::_notification(int p_what) { if (refresh_countdown <= 0) { for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) { - E->get()->update_property(); - E->get()->update_reload_status(); + if (!E->get()->is_cache_valid()) { + E->get()->update_property(); + E->get()->update_reload_status(); + E->get()->update_cache(); + } } } + refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); } } @@ -2445,6 +2489,7 @@ void EditorInspector::_notification(int p_what) { for (List<EditorProperty *>::Element *E = editor_property_map[prop].front(); E; E = E->next()) { E->get()->update_property(); E->get()->update_reload_status(); + E->get()->update_cache(); } } pending.erase(pending.front()); @@ -2455,19 +2500,17 @@ void EditorInspector::_notification(int p_what) { } if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - if (sub_inspector) { - add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor")); - } else if (is_inside_tree()) { - add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); - } + _update_inspector_bg(); update_tree(); } } -void EditorInspector::_changed_callback(Object *p_changed, const char *p_prop) { - //this is called when property change is notified via _change_notify() - _edit_request_change(p_changed, p_prop); +void EditorInspector::_changed_callback() { + //this is called when property change is notified via notify_property_list_changed() + if (object != nullptr) { + _edit_request_change(object, String()); + } } void EditorInspector::_vscroll_changed(double p_offset) { @@ -2506,22 +2549,11 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li return; } - List<StringName> classes; - Map<StringName, String> paths; + List<Ref<Script>> classes; // NodeC -> NodeB -> NodeA while (script.is_valid()) { - String n = EditorNode::get_editor_data().script_class_get_name(script->get_path()); - if (n.length()) { - classes.push_front(n); - } else if (script->get_path() != String() && script->get_path().find("::") == -1) { - n = script->get_path().get_file(); - classes.push_front(n); - } else { - n = TTR("Built-in script"); - classes.push_front(n); - } - paths[n] = script->get_path(); + classes.push_front(script); script = script->get_base_script(); } @@ -2545,17 +2577,18 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li } Set<StringName> added; - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - StringName name = E->get(); - String path = paths[name]; - Ref<Script> s; - if (path == String()) { - // Built-in script. It can't be inherited, so must be the script attached to the object. - s = p_object.get_script(); - } else { - s = ResourceLoader::load(path, "Script"); + for (List<Ref<Script>>::Element *E = classes.front(); E; E = E->next()) { + Ref<Script> s = E->get(); + String path = s->get_path(); + String name = EditorNode::get_editor_data().script_class_get_name(path); + if (name.is_empty()) { + if (!path.is_empty() && path.find("::") == -1) { + name = path.get_file(); + } else { + name = TTR("Built-in script"); + } } - ERR_FAIL_COND(!s->is_valid()); + List<PropertyInfo> props; s->get_script_property_list(&props); @@ -2590,8 +2623,6 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li void EditorInspector::_bind_methods() { ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change); - ClassDB::bind_method("refresh", &EditorInspector::refresh); - ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property"))); @@ -2623,16 +2654,21 @@ EditorInspector::EditorInspector() { use_folding = false; update_all_pending = false; update_tree_pending = false; - refresh_countdown = 0; read_only = false; search_box = nullptr; keying = false; _prop_edited = "property_edited"; - set_process(true); + set_process(false); property_focusable = -1; sub_inspector = false; deletable_properties = false; get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed)); update_scroll_request = -1; + if (EditorSettings::get_singleton()) { + refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval")); + } else { + //used when class is created by the docgen to dump default values of everything bindable, editorsettings may not be created + refresh_countdown = 0.33; + } } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 81a22d4ff1..b98801975f 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -98,6 +98,8 @@ private: mutable String tooltip_text; + Map<StringName, Variant> cache; + protected: void _notification(int p_what); static void _bind_methods(); @@ -152,6 +154,8 @@ public: virtual void collapse_all_folding(); virtual Variant get_drag_data(const Point2 &p_point) override; + virtual void update_cache(); + virtual bool is_cache_valid() const; void set_selectable(bool p_selectable); bool is_selectable() const; @@ -326,7 +330,7 @@ class EditorInspector : public ScrollContainer { void _node_removed(Node *p_node); - void _changed_callback(Object *p_changed, const char *p_prop) override; + void _changed_callback(); void _edit_request_change(Object *p_object, const String &p_prop); void _filter_changed(const String &p_text); @@ -339,6 +343,8 @@ class EditorInspector : public ScrollContainer { bool _is_property_disabled_by_feature_profile(const StringName &p_property); + void _update_inspector_bg(); + protected: static void _bind_methods(); void _notification(int p_what); @@ -356,9 +362,6 @@ public: void update_tree(); void update_property(const String &p_prop); - - void refresh(); - void edit(Object *p_object); Object *get_edited_object(); @@ -393,6 +396,7 @@ public: void set_use_wide_editors(bool p_enable); void set_sub_inspector(bool p_enable); + bool is_sub_inspector() const { return sub_inspector; } void set_use_deletable_properties(bool p_enabled); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 040f1b1640..045480868d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -517,8 +517,6 @@ void EditorNode::_notification(int p_what) { RS::get_singleton()->gi_probe_set_quality(gi_probe_quality); RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth")); RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/volumetric_fog/use_filter"))); - RS::get_singleton()->environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink")); - RS::get_singleton()->environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size")); bool use_half_res_gi = GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false); @@ -596,6 +594,7 @@ void EditorNode::_notification(int p_what) { OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); EditorFileSystem::get_singleton()->scan_changes(); + _scan_external_changes(); } break; case NOTIFICATION_APPLICATION_FOCUS_OUT: { @@ -888,6 +887,81 @@ void EditorNode::_sources_changed(bool p_exist) { } } +void EditorNode::_scan_external_changes() { + disk_changed_list->clear(); + TreeItem *r = disk_changed_list->create_item(); + disk_changed_list->set_hide_root(true); + bool need_reload = false; + + // Check if any edited scene has changed. + + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + if (editor_data.get_scene_path(i) == "") { + continue; + } + + uint64_t last_date = editor_data.get_scene_modified_time(i); + uint64_t date = FileAccess::get_modified_time(editor_data.get_scene_path(i)); + + if (date > last_date) { + TreeItem *ti = disk_changed_list->create_item(r); + ti->set_text(0, editor_data.get_scene_path(i).get_file()); + need_reload = true; + } + } + + String project_settings_path = ProjectSettings::get_singleton()->get_resource_path().plus_file("project.godot"); + if (FileAccess::get_modified_time(project_settings_path) > ProjectSettings::get_singleton()->get_last_saved_time()) { + TreeItem *ti = disk_changed_list->create_item(r); + ti->set_text(0, "project.godot"); + need_reload = true; + } + + if (need_reload) { + disk_changed->call_deferred("popup_centered_ratio", 0.5); + } +} + +void EditorNode::_resave_scenes(String p_str) { + save_all_scenes(); + ProjectSettings::get_singleton()->save(); + disk_changed->hide(); +} + +void EditorNode::_reload_modified_scenes() { + int current_idx = editor_data.get_edited_scene(); + + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + if (editor_data.get_scene_path(i) == "") { + continue; + } + + uint64_t last_date = editor_data.get_scene_modified_time(i); + uint64_t date = FileAccess::get_modified_time(editor_data.get_scene_path(i)); + + if (date > last_date) { + String filename = editor_data.get_scene_path(i); + editor_data.set_edited_scene(i); + _remove_edited_scene(false); + + Error err = load_scene(filename, false, false, true, false, true); + if (err != OK) { + ERR_PRINT(vformat("Failed to load scene: %s", filename)); + } + editor_data.move_edited_scene_to_index(i); + } + } + + get_undo_redo()->clear_history(false); + set_current_scene(current_idx); + _update_scene_tabs(); + disk_changed->hide(); +} + +void EditorNode::_reload_project_settings() { + ProjectSettings::get_singleton()->setup(ProjectSettings::get_singleton()->get_resource_path(), String(), true); +} + void EditorNode::_vp_resized() { } @@ -929,7 +1003,7 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d dependency_errors.clear(); Error err; - RES res = ResourceLoader::load(p_resource, "", false, &err); + RES res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN); if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) { @@ -1513,6 +1587,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } else { editor_data.set_edited_scene_version(0, idx); } + editor_data.set_scene_modified_time(idx, FileAccess::get_modified_time(p_file)); editor_folding.save_scene_folding(scene, p_file); @@ -1716,7 +1791,7 @@ void EditorNode::_dialog_action(String p_file) { ObjectID current = editor_history.get_current(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; ERR_FAIL_COND(!current_obj); - current_obj->_change_notify(); + current_obj->notify_property_list_changed(); } break; case SETTINGS_LAYOUT_SAVE: { if (p_file.is_empty()) { @@ -3328,7 +3403,7 @@ int EditorNode::new_scene() { return idx; } -Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) { +Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported, bool p_silent_change_tab) { if (!is_inside_tree()) { defer_load_scene = p_scene; return OK; @@ -3368,14 +3443,16 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count() == 2) { _remove_edited_scene(); - } else { + } else if (!p_silent_change_tab) { _scene_tab_changed(idx); + } else { + set_current_scene(idx); } dependency_errors.clear(); Error err; - Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err); + Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err); if (!sdata.is_valid()) { _dialog_display_load_error(lpath, err); opening_prev = false; @@ -5197,6 +5274,8 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) { } void EditorNode::reload_scene(const String &p_path) { + /* + * No longer necesary since scenes now reset and reload their internal resource if needed. //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk List<Ref<Resource>> cached; @@ -5214,6 +5293,8 @@ void EditorNode::reload_scene(const String &p_path) { to_clear.pop_front(); } + */ + int scene_idx = -1; for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { if (editor_data.get_scene_path(i) == p_path) { @@ -5777,7 +5858,7 @@ EditorNode::EditorNode() { EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false); EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true); EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true); - EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "StandardMaterial3D,ORMMaterial3D,Script,MeshLibrary,TileSet"); + EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary,TileSet"); EDITOR_DEF("interface/inspector/default_color_picker_mode", 0); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); @@ -6265,7 +6346,7 @@ EditorNode::EditorNode() { p = help_menu->get_popup(); p->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option)); - p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search"), KEY_MASK_SHIFT | KEY_F1), HELP_SEARCH); + p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search")), HELP_SEARCH); p->add_separator(); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Docs")), HELP_DOCS); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/q&a", TTR("Q&A")), HELP_QA); @@ -6603,6 +6684,30 @@ EditorNode::EditorNode() { //plugin stuff add_editor_plugin(memnew(DebuggerEditorPlugin(this, debug_menu))); + + disk_changed = memnew(ConfirmationDialog); + { + VBoxContainer *vbc = memnew(VBoxContainer); + disk_changed->add_child(vbc); + + Label *dl = memnew(Label); + dl->set_text(TTR("The following files are newer on disk.\nWhat action should be taken?")); + vbc->add_child(dl); + + disk_changed_list = memnew(Tree); + vbc->add_child(disk_changed_list); + disk_changed_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_modified_scenes)); + disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_project_settings)); + disk_changed->get_ok_button()->set_text(TTR("Reload")); + + disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); + disk_changed->connect("custom_action", callable_mp(this, &EditorNode::_resave_scenes)); + } + + gui_base->add_child(disk_changed); + add_editor_plugin(memnew(AnimationPlayerEditorPlugin(this))); add_editor_plugin(memnew(CanvasItemEditorPlugin(this))); add_editor_plugin(memnew(Node3DEditorPlugin(this))); diff --git a/editor/editor_node.h b/editor/editor_node.h index 356ac0caac..3785d29c41 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -422,6 +422,9 @@ private: Label *version_label; Button *bottom_panel_raise; + Tree *disk_changed_list; + ConfirmationDialog *disk_changed; + void _bottom_panel_raise_toggled(bool); EditorInterface *editor_interface; @@ -641,6 +644,10 @@ private: static void _resource_loaded(RES p_resource, const String &p_path); void _resources_changed(const Vector<String> &p_resources); + void _scan_external_changes(); + void _reload_modified_scenes(); + void _reload_project_settings(); + void _resave_scenes(String p_str); void _feature_profile_changed(); bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class); @@ -741,7 +748,7 @@ public: void fix_dependencies(const String &p_for_file); void clear_scene() { _cleanup_scene(); } int new_scene(); - Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false); + Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false, bool p_silent_change_tab = false); Error load_resource(const String &p_resource, bool p_ignore_broken_deps = false); bool is_scene_open(const String &p_path); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 4d8a4f46b2..6bfc16ccd7 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1267,16 +1267,20 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); - + bool grid = false; BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); add_child(bc); } else if (horizontal) { - bc = memnew(HBoxContainer); + bc = memnew(VBoxContainer); add_child(bc); set_bottom_editor(bc); + + bc->add_child(memnew(HBoxContainer)); + bc->add_child(memnew(HBoxContainer)); + grid = true; } else { bc = memnew(VBoxContainer); add_child(bc); @@ -1287,7 +1291,13 @@ EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); spin[i]->set_flat(true); - bc->add_child(spin[i]); + + if (grid) { + bc->get_child(i / 2)->add_child(spin[i]); + } else { + bc->add_child(spin[i]); + } + add_focusable(spin[i]); spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2::_value_changed), varray(desc[i])); if (horizontal) { @@ -1530,16 +1540,20 @@ void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) { EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); - + bool grid = false; BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); add_child(bc); } else if (horizontal) { - bc = memnew(HBoxContainer); + bc = memnew(VBoxContainer); add_child(bc); set_bottom_editor(bc); + + bc->add_child(memnew(HBoxContainer)); + bc->add_child(memnew(HBoxContainer)); + grid = true; } else { bc = memnew(VBoxContainer); add_child(bc); @@ -1550,7 +1564,13 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { spin[i] = memnew(EditorSpinSlider); spin[i]->set_label(desc[i]); spin[i]->set_flat(true); - bc->add_child(spin[i]); + + if (grid) { + bc->get_child(i / 2)->add_child(spin[i]); + } else { + bc->add_child(spin[i]); + } + add_focusable(spin[i]); spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i])); if (horizontal) { @@ -2839,6 +2859,41 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) { } } +void EditorPropertyResource::_update_property_bg() { + if (!is_inside_tree()) { + return; + } + + updating_theme = true; + if (sub_inspector != nullptr) { + int count_subinspectors = 0; + Node *n = get_parent(); + while (n) { + EditorInspector *ei = Object::cast_to<EditorInspector>(n); + if (ei && ei->is_sub_inspector()) { + count_subinspectors++; + } + n = n->get_parent(); + } + count_subinspectors = MIN(15, count_subinspectors); + + add_theme_color_override("property_color", get_theme_color("sub_inspector_property_color", "Editor")); + add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), "Editor")); + add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), "Editor")); + + add_theme_constant_override("font_offset", get_theme_constant("sub_inspector_font_offset", "Editor")); + add_theme_constant_override("vseparation", 0); + } else { + add_theme_color_override("property_color", get_theme_color("property_color", "EditorProperty")); + add_theme_style_override("bg_selected", get_theme_stylebox("bg_selected", "EditorProperty")); + add_theme_style_override("bg", get_theme_stylebox("bg", "EditorProperty")); + add_theme_constant_override("vseparation", get_theme_constant("vseparation", "EditorProperty")); + add_theme_constant_override("font_offset", get_theme_constant("font_offset", "EditorProperty")); + } + + updating_theme = false; + update(); +} void EditorPropertyResource::update_property() { RES res = get_edited_object()->get(get_edited_property()); @@ -2887,13 +2942,14 @@ void EditorPropertyResource::update_property() { } opened_editor = true; } + + _update_property_bg(); } if (res.ptr() != sub_inspector->get_edited_object()) { sub_inspector->edit(res.ptr()); } - sub_inspector->refresh(); } else { if (sub_inspector) { set_bottom_editor(nullptr); @@ -2904,6 +2960,7 @@ void EditorPropertyResource::update_property() { EditorNode::get_singleton()->hide_top_editors(); opened_editor = false; } + _update_property_bg(); } } } @@ -2957,8 +3014,12 @@ void EditorPropertyResource::setup(const String &p_base_type) { void EditorPropertyResource::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + if (updating_theme) { + return; + } Ref<Texture2D> t = get_theme_icon("select_arrow", "Tree"); edit->set_icon(t); + _update_property_bg(); } if (p_what == NOTIFICATION_DRAG_BEGIN) { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 4775259111..6f097fb5df 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -654,6 +654,9 @@ class EditorPropertyResource : public EditorProperty { bool opened_editor; + bool updating_theme = false; + void _update_property_bg(); + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index a2627f51ac..fb4821a760 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -116,12 +116,12 @@ public: void set_section(const String &p_section, bool p_allow_sub) { section = p_section; allow_sub = p_allow_sub; - _change_notify(); + notify_property_list_changed(); } void set_edited(Object *p_edited) { edited = p_edited; - _change_notify(); + notify_property_list_changed(); } }; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 7a602912c9..e37173bf68 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -441,7 +441,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("docks/filesystem/always_show_folders", true); // Property editor - _initial_set("docks/property_editor/auto_refresh_interval", 0.3); + _initial_set("docks/property_editor/auto_refresh_interval", 0.2); //update 5 times per second by default + _initial_set("docks/property_editor/subresource_hue_tint", 0.75); + hints["docks/property_editor/subresource_hue_tint"] = PropertyInfo(Variant::FLOAT, "docks/property_editor/subresource_hue_tint", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT); /* Text editor */ @@ -959,27 +961,16 @@ void EditorSettings::create() { _create_script_templates(dir->get_current_dir().plus_file("script_templates")); - if (dir->change_dir("projects") != OK) { - dir->make_dir("projects"); - } else { - dir->change_dir(".."); - } - - // Validate/create project-specific config dir - - dir->change_dir("projects"); - String project_config_dir = ProjectSettings::get_singleton()->get_resource_path(); - if (project_config_dir.ends_with("/")) { - project_config_dir = config_path.substr(0, project_config_dir.size() - 1); - } - project_config_dir = project_config_dir.get_file() + "-" + project_config_dir.md5_text(); - - if (dir->change_dir(project_config_dir) != OK) { - dir->make_dir(project_config_dir); - } else { - dir->change_dir(".."); + { + // Validate/create project-specific editor settings dir. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) { + Error err = da->make_dir_recursive(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH); + if (err || da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) { + ERR_FAIL_MSG("Failed to create '" + EditorSettings::PROJECT_EDITOR_SETTINGS_PATH + "' folder."); + } + } } - dir->change_dir(".."); // Validate editor config file @@ -1001,7 +992,6 @@ void EditorSettings::create() { singleton->save_changed_setting = true; singleton->config_file_path = config_file_path; - singleton->project_config_dir = project_config_dir; singleton->settings_dir = config_dir; singleton->data_dir = data_dir; singleton->cache_dir = cache_dir; @@ -1277,7 +1267,7 @@ String EditorSettings::get_settings_dir() const { } String EditorSettings::get_project_settings_dir() const { - return get_settings_dir().plus_file("projects").plus_file(project_config_dir); + return EditorSettings::PROJECT_EDITOR_SETTINGS_PATH; } String EditorSettings::get_text_editor_themes_dir() const { diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 61ec8546aa..616a938a86 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -46,6 +46,7 @@ class EditorSettings : public Resource { _THREAD_SAFE_CLASS_ public: + inline static const String PROJECT_EDITOR_SETTINGS_PATH = "res://.godot/editor"; struct Plugin { EditorPlugin *instance = nullptr; String path; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 8f877a4762..f81087ded9 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -724,14 +724,58 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons")); theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size + 1) * EDSCALE); - Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(accent_color, 0.08), 2, 0, 2, 2); - sub_inspector_bg->set_border_width(SIDE_LEFT, 2); - sub_inspector_bg->set_border_width(SIDE_RIGHT, 2); - sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2); - sub_inspector_bg->set_border_color(accent_color * Color(1, 1, 1, 0.3)); - sub_inspector_bg->set_draw_center(true); - - theme->set_stylebox("sub_inspector_bg", "Editor", sub_inspector_bg); + for (int i = 0; i < 16; i++) { + Color si_base_color = accent_color; + + float hue_rotate = (i * 2 % 16) / 16.0; + si_base_color.set_hsv(Math::fmod(float(si_base_color.get_h() + hue_rotate), float(1.0)), si_base_color.get_s(), si_base_color.get_v()); + si_base_color = accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint"))); + + Ref<StyleBoxFlat> sub_inspector_bg; + + sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(si_base_color, 0.08), 2, 0, 2, 2); + + sub_inspector_bg->set_border_width(SIDE_LEFT, 2); + sub_inspector_bg->set_border_width(SIDE_RIGHT, 2); + sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2); + sub_inspector_bg->set_border_width(SIDE_TOP, 2); + sub_inspector_bg->set_default_margin(SIDE_LEFT, 3); + sub_inspector_bg->set_default_margin(SIDE_RIGHT, 3); + sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 10); + sub_inspector_bg->set_default_margin(SIDE_TOP, 5); + sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); + sub_inspector_bg->set_draw_center(true); + + theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg); + + Ref<StyleBoxFlat> bg_color; + bg_color.instance(); + bg_color->set_bg_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); + bg_color->set_border_width_all(0); + + Ref<StyleBoxFlat> bg_color_selected; + bg_color_selected.instance(); + bg_color_selected->set_border_width_all(0); + bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8)); + + theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color); + theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected); + } + + theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); + theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE); + + Ref<StyleBoxFlat> style_property_bg = style_default->duplicate(); + style_property_bg->set_bg_color(highlight_color); + style_property_bg->set_border_width_all(0); + + theme->set_constant("font_offset", "EditorProperty", 1 * EDSCALE); + theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); + theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); + theme->set_color("error_color", "EditorProperty", error_color); + theme->set_color("property_color", "EditorProperty", property_color); + theme->set_constant("inspector_margin", "Editor", 8 * EDSCALE); // Tree & ItemList background diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index e1c66f43b9..ab5fd30998 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1411,14 +1411,26 @@ void FileSystemDock::_make_scene_confirm() { void FileSystemDock::_file_removed(String p_file) { emit_signal("file_removed", p_file); - path = "res://"; + // Find the closest parent directory available, in case multiple items were deleted along the same path. + path = p_file.get_base_dir(); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (!da->dir_exists(path)) { + path = path.get_base_dir(); + } + current_path->set_text(path); } void FileSystemDock::_folder_removed(String p_folder) { emit_signal("folder_removed", p_folder); - path = "res://"; + // Find the closest parent directory available, in case multiple items were deleted along the same path. + path = p_folder.get_base_dir(); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (!da->dir_exists(path)) { + path = path.get_base_dir(); + } + current_path->set_text(path); } @@ -1586,7 +1598,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_ove print_verbose("FileSystem: saving moved scenes."); _save_scenes_after_move(file_renames); - path = "res://"; + path = p_to_path; current_path->set_text(path); } } diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 9944712931..d0e5798045 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -964,7 +964,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String if (FileAccess::exists(ext_name) && p_keep_animations) { // Copy custom animation tracks from previously imported files. - Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", true); + Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE); if (old_anim.is_valid()) { for (int i = 0; i < old_anim->get_track_count(); i++) { if (!old_anim->track_is_imported(i)) { @@ -1004,7 +1004,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String p_materials[mat] = ResourceLoader::load(ext_name); } else { ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache. + p_materials[mat] = ResourceLoader::load(ext_name, "", ResourceFormatLoader::CACHE_MODE_IGNORE); // disable loading from the cache. } } @@ -1061,7 +1061,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String p_materials[mat] = ResourceLoader::load(ext_name); } else { ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache. + p_materials[mat] = ResourceLoader::load(ext_name, "", ResourceFormatLoader::CACHE_MODE_IGNORE); // disable loading from the cache. } } diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 103e5e81cb..97a04e6557 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -48,7 +48,7 @@ public: values[p_name] = p_value; if (checking) { checked.insert(p_name); - _change_notify(); + notify_property_list_changed(); } return true; } @@ -81,7 +81,7 @@ public: } void update() { - _change_notify(); + notify_property_list_changed(); } ImportDockParameters() { diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index 96ebb131ad..bd825d0802 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -844,7 +844,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec //min_p = p_arc_xform.affine_inverse().xform(min_p); float a = (Math_PI * 0.5) - Vector2(min_p.x, -min_p.z).angle(); - return a * 180.0 / Math_PI; + return Math::rad2deg(a); } void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { @@ -1033,12 +1033,9 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_lines(points_primary, material_primary, false, color); p_gizmo->add_lines(points_secondary, material_secondary, false, color); - const float ra = 16 * Math_PI * 2.0 / 64.0; - const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w; - Vector<Vector3> handles; handles.push_back(Vector3(0, 0, -r)); - handles.push_back(Vector3(a.x, a.y, -d)); + handles.push_back(Vector3(w, 0, -d)); p_gizmo->add_handles(handles, get_material("handles")); p_gizmo->add_unscaled_billboard(icon, 0.05, color); @@ -1095,8 +1092,8 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int float closest_angle = 1e20; for (int i = 0; i < 180; i++) { - float a = i * Math_PI / 180.0; - float an = (i + 1) * Math_PI / 180.0; + float a = Math::deg2rad((float)i); + float an = Math::deg2rad((float)(i + 1)); Vector3 from(Math::sin(a), 0, -Math::cos(a)); Vector3 to(Math::sin(an), 0, -Math::cos(an)); @@ -1145,9 +1142,10 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> points_primary; points_primary.resize(200); + real_t step = Math_TAU / 100.0; for (int i = 0; i < 100; i++) { - const float a = i * 2.0 * Math_PI / 100.0; - const float an = (i + 1) * 2.0 * Math_PI / 100.0; + const float a = i * step; + const float an = (i + 1) * step; const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs); const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs); @@ -1163,7 +1161,7 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { points_secondary.resize(16); for (int i = 0; i < 8; i++) { - const float a = i * 2.0 * Math_PI / 8.0; + const float a = i * (Math_TAU / 8.0); const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs); points_secondary.write[i * 2 + 0] = from; @@ -2616,8 +2614,8 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; @@ -3317,7 +3315,7 @@ void BakedLightmapGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { int stack_count = 8; int sector_count = 16; - float sector_step = 2 * Math_PI / sector_count; + float sector_step = (Math_PI * 2.0) / sector_count; float stack_step = Math_PI / stack_count; Vector<Vector3> vertices; @@ -3454,7 +3452,7 @@ void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { int stack_count = 8; int sector_count = 16; - float sector_step = 2 * Math_PI / sector_count; + float sector_step = (Math_PI * 2.0) / sector_count; float stack_step = Math_PI / stack_count; Vector<Vector3> vertices; @@ -3854,8 +3852,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; @@ -3939,8 +3937,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; @@ -4002,8 +4000,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Vector<Vector3> collision_segments; for (int i = 0; i < 64; i++) { - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; + float ra = i * (Math_TAU / 64.0); + float rb = (i + 1) * (Math_TAU / 64.0); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 56d82acd2f..cda88c00f3 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -78,7 +78,6 @@ void AnimationPlayerEditor::_notification(int p_what) { } frame->set_value(player->get_current_animation_position()); track_editor->set_anim_pos(player->get_current_animation_position()); - EditorNode::get_singleton()->get_inspector()->refresh(); } else if (!player->is_valid()) { // Reset timeline when the player has been stopped externally @@ -1072,8 +1071,6 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) frame->set_value(Math::snapped(p_pos, _get_editor_step())); updating = false; _seek_value_changed(p_pos, !p_drag); - - EditorNode::get_singleton()->get_inspector()->refresh(); } void AnimationPlayerEditor::_animation_tool_menu(int p_option) { diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index 1765c99572..5963092860 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -96,7 +96,7 @@ void AudioStreamEditor::_preview_changed(ObjectID p_which) { } } -void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void AudioStreamEditor::_audio_changed() { if (!is_visible()) { return; } @@ -172,7 +172,7 @@ void AudioStreamEditor::_seek_to(real_t p_x) { void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { if (!stream.is_null()) { - stream->remove_change_receptor(this); + stream->disconnect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); } stream = p_stream; @@ -182,7 +182,7 @@ void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { _duration_label->set_text(text); if (!stream.is_null()) { - stream->add_change_receptor(this); + stream->connect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); update(); } else { hide(); diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h index f27add7229..aa906a6a05 100644 --- a/editor/plugins/audio_stream_editor_plugin.h +++ b/editor/plugins/audio_stream_editor_plugin.h @@ -53,6 +53,8 @@ class AudioStreamEditor : public ColorRect { float _current; bool _dragging; + void _audio_changed(); + protected: void _notification(int p_what); void _preview_changed(ObjectID p_which); @@ -63,7 +65,6 @@ protected: void _draw_indicator(); void _on_input_indicator(Ref<InputEvent> p_event); void _seek_to(real_t p_x); - void _changed_callback(Object *p_changed, const char *p_prop) override; static void _bind_methods(); public: diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 63f74b5ca9..d92837b68d 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -216,8 +216,8 @@ public: grid_step_x->set_value(p_grid_step.x); grid_step_y->set_value(p_grid_step.y); primary_grid_steps->set_value(p_primary_grid_steps); - rotation_offset->set_value(p_rotation_offset * (180 / Math_PI)); - rotation_step->set_value(p_rotation_step * (180 / Math_PI)); + rotation_offset->set_value(Math::rad2deg(p_rotation_offset)); + rotation_step->set_value(Math::rad2deg(p_rotation_step)); scale_step->set_value(p_scale_step); } @@ -225,8 +225,8 @@ public: p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value()); p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value()); p_primary_grid_steps = int(primary_grid_steps->get_value()); - p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI); - p_rotation_step = rotation_step->get_value() / (180 / Math_PI); + p_rotation_offset = Math::deg2rad(rotation_offset->get_value()); + p_rotation_step = Math::deg2rad(rotation_step->get_value()); p_scale_step = scale_step->get_value(); } }; @@ -5638,7 +5638,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { primary_grid_steps = 8; // A power-of-two value works better as a default grid_step_multiplier = 0; snap_rotation_offset = 0; - snap_rotation_step = 15 / (180 / Math_PI); + snap_rotation_step = Math::deg2rad(15.0); snap_scale_step = 0.1f; smart_snap_active = false; grid_snap_active = false; diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index a1e7d3d6e0..141ee35cdb 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -207,7 +207,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } break; } - node->get_shape()->_change_notify(); + node->get_shape()->notify_property_list_changed(); } void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index bdf88b82e4..63bb785c5e 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -382,7 +382,9 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { int lats = 32; int lons = 32; - float radius = 1.0; + const double lat_step = Math_TAU / lats; + const double lon_step = Math_TAU / lons; + real_t radius = 1.0; Vector<Vector3> vertices; Vector<Vector3> normals; @@ -391,20 +393,20 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { Basis tt = Basis(Vector3(0, 1, 0), Math_PI * 0.5); for (int i = 1; i <= lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index c0f690bb6a..1ea6630622 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -145,7 +145,7 @@ int ItemListOptionButtonPlugin::get_flags() const { void ItemListOptionButtonPlugin::add_item() { ob->add_item(vformat(TTR("Item %d"), ob->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListOptionButtonPlugin::get_item_count() const { @@ -154,7 +154,7 @@ int ItemListOptionButtonPlugin::get_item_count() const { void ItemListOptionButtonPlugin::erase(int p_idx) { ob->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() { @@ -181,7 +181,7 @@ int ItemListPopupMenuPlugin::get_flags() const { void ItemListPopupMenuPlugin::add_item() { pp->add_item(vformat(TTR("Item %d"), pp->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListPopupMenuPlugin::get_item_count() const { @@ -190,7 +190,7 @@ int ItemListPopupMenuPlugin::get_item_count() const { void ItemListPopupMenuPlugin::erase(int p_idx) { pp->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() { @@ -213,7 +213,7 @@ int ItemListItemListPlugin::get_flags() const { void ItemListItemListPlugin::add_item() { pp->add_item(vformat(TTR("Item %d"), pp->get_item_count())); - _change_notify(); + notify_property_list_changed(); } int ItemListItemListPlugin::get_item_count() const { @@ -222,7 +222,7 @@ int ItemListItemListPlugin::get_item_count() const { void ItemListItemListPlugin::erase(int p_idx) { pp->remove_item(p_idx); - _change_notify(); + notify_property_list_changed(); } ItemListItemListPlugin::ItemListItemListPlugin() { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index dcf38e0617..a3009731f9 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2493,6 +2493,13 @@ void Node3DEditorViewport::_notification(int p_what) { text += "Z: " + rtos(current_camera->get_translation().z).pad_decimals(1) + "\n"; text += TTR("Pitch") + ": " + itos(Math::round(current_camera->get_rotation_degrees().x)) + "\n"; text += TTR("Yaw") + ": " + itos(Math::round(current_camera->get_rotation_degrees().y)) + "\n\n"; + + text += TTR("Size") + + vformat( + ": %dx%d (%.1fMP)\n", + viewport->get_size().x, + viewport->get_size().y, + viewport->get_size().x * viewport->get_size().y * 0.000'001); text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n"; text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n"; text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n"; @@ -2824,7 +2831,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { } break; case VIEW_FRONT: { cursor.x_rot = 0; - cursor.y_rot = 0; + cursor.y_rot = Math_PI; set_message(TTR("Front View."), 2); name = TTR("Front"); _set_auto_orthogonal(); @@ -2833,7 +2840,7 @@ void Node3DEditorViewport::_menu_option(int p_option) { } break; case VIEW_REAR: { cursor.x_rot = 0; - cursor.y_rot = Math_PI; + cursor.y_rot = 0; set_message(TTR("Rear View."), 2); name = TTR("Rear"); _set_auto_orthogonal(); @@ -5259,6 +5266,42 @@ void Node3DEditor::_init_indicators() { origin_points.push_back(axis * -1048576); } + Ref<Shader> grid_shader = memnew(Shader); + grid_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded; \n" + "uniform bool orthogonal; \n" + "uniform float grid_size; \n" + "\n" + "void vertex() { \n" + " // From FLAG_SRGB_VERTEX_COLOR \n" + " if (!OUTPUT_IS_SRGB) { \n" + " COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045))); \n" + " } \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = COLOR.rgb; \n" + " vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n" + " float angle_fade = abs(dot(dir, NORMAL)); \n" + " angle_fade = smoothstep(0.05, 0.2, angle_fade); \n" + " \n" + " vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n" + " vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n" + " vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n" + " vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n" + " float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n" + " dist_fade = smoothstep(0.02, 0.3, dist_fade); \n" + " \n" + " ALPHA = COLOR.a * dist_fade * angle_fade; \n" + "}"); + + for (int i = 0; i < 3; i++) { + grid_mat[i].instance(); + grid_mat[i]->set_shader(grid_shader); + } + grid_enable[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane"); grid_enable[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane"); grid_enable[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane"); @@ -5351,9 +5394,10 @@ void Node3DEditor::_init_indicators() { int arrow_sides = 16; + const real_t arrow_sides_step = Math_TAU / arrow_sides; for (int k = 0; k < arrow_sides; k++) { - Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides); - Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides); + Basis ma(ivec, k * arrow_sides_step); + Basis mb(ivec, (k + 1) * arrow_sides_step); for (int j = 0; j < arrow_points - 1; j++) { Vector3 points[4] = { @@ -5428,13 +5472,14 @@ void Node3DEditor::_init_indicators() { int n = 128; // number of circle segments int m = 6; // number of thickness segments + real_t step = Math_TAU / n; for (int j = 0; j < n; ++j) { - Basis basis = Basis(ivec, (Math_PI * 2.0f * j) / n); + Basis basis = Basis(ivec, j * step); Vector3 vertex = basis.xform(ivec2 * GIZMO_CIRCLE_SIZE); for (int k = 0; k < m; ++k) { - Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m)); + Vector2 ofs = Vector2(Math::cos((Math_TAU * k) / m), Math::sin((Math_TAU * k) / m)); Vector3 normal = ivec * ofs.x + ivec2 * ofs.y; surftool->set_normal(basis.xform(normal)); @@ -5461,32 +5506,33 @@ void Node3DEditor::_init_indicators() { Ref<Shader> rotate_shader = memnew(Shader); - rotate_shader->set_code("\n" - "shader_type spatial; \n" - "render_mode unshaded, depth_test_disabled; \n" - "uniform vec4 albedo; \n" - "\n" - "mat3 orthonormalize(mat3 m) { \n" - " vec3 x = normalize(m[0]); \n" - " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" - " vec3 z = m[2] - x * dot(x, m[2]); \n" - " z = normalize(z - y * (dot(y,m[2]))); \n" - " return mat3(x,y,z); \n" - "} \n" - "\n" - "void vertex() { \n" - " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" - " vec3 n = mv * VERTEX; \n" - " float orientation = dot(vec3(0,0,-1),n); \n" - " if (orientation <= 0.005) { \n" - " VERTEX += NORMAL*0.02; \n" - " } \n" - "} \n" - "\n" - "void fragment() { \n" - " ALBEDO = albedo.rgb; \n" - " ALPHA = albedo.a; \n" - "}"); + rotate_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded, depth_test_disabled; \n" + "uniform vec4 albedo; \n" + "\n" + "mat3 orthonormalize(mat3 m) { \n" + " vec3 x = normalize(m[0]); \n" + " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" + " vec3 z = m[2] - x * dot(x, m[2]); \n" + " z = normalize(z - y * (dot(y,m[2]))); \n" + " return mat3(x,y,z); \n" + "} \n" + "\n" + "void vertex() { \n" + " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" + " vec3 n = mv * VERTEX; \n" + " float orientation = dot(vec3(0,0,-1),n); \n" + " if (orientation <= 0.005) { \n" + " VERTEX += NORMAL*0.02; \n" + " } \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = albedo.rgb; \n" + " ALPHA = albedo.a; \n" + "}"); Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial); rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX); @@ -5506,33 +5552,34 @@ void Node3DEditor::_init_indicators() { Ref<ShaderMaterial> border_mat = rotate_mat->duplicate(); Ref<Shader> border_shader = memnew(Shader); - border_shader->set_code("\n" - "shader_type spatial; \n" - "render_mode unshaded, depth_test_disabled; \n" - "uniform vec4 albedo; \n" - "\n" - "mat3 orthonormalize(mat3 m) { \n" - " vec3 x = normalize(m[0]); \n" - " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" - " vec3 z = m[2] - x * dot(x, m[2]); \n" - " z = normalize(z - y * (dot(y,m[2]))); \n" - " return mat3(x,y,z); \n" - "} \n" - "\n" - "void vertex() { \n" - " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" - " mv = inverse(mv); \n" - " VERTEX += NORMAL*0.008; \n" - " vec3 camera_dir_local = mv * vec3(0,0,1); \n" - " vec3 camera_up_local = mv * vec3(0,1,0); \n" - " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" - " VERTEX = rotation_matrix * VERTEX; \n" - "} \n" - "\n" - "void fragment() { \n" - " ALBEDO = albedo.rgb; \n" - " ALPHA = albedo.a; \n" - "}"); + border_shader->set_code( + "\n" + "shader_type spatial; \n" + "render_mode unshaded, depth_test_disabled; \n" + "uniform vec4 albedo; \n" + "\n" + "mat3 orthonormalize(mat3 m) { \n" + " vec3 x = normalize(m[0]); \n" + " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n" + " vec3 z = m[2] - x * dot(x, m[2]); \n" + " z = normalize(z - y * (dot(y,m[2]))); \n" + " return mat3(x,y,z); \n" + "} \n" + "\n" + "void vertex() { \n" + " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n" + " mv = inverse(mv); \n" + " VERTEX += NORMAL*0.008; \n" + " vec3 camera_dir_local = mv * vec3(0,0,1); \n" + " vec3 camera_up_local = mv * vec3(0,1,0); \n" + " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n" + " VERTEX = rotation_matrix * VERTEX; \n" + "} \n" + "\n" + "void fragment() { \n" + " ALBEDO = albedo.rgb; \n" + " ALPHA = albedo.a; \n" + "}"); border_mat->set_shader(border_shader); border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); @@ -5561,9 +5608,10 @@ void Node3DEditor::_init_indicators() { int arrow_sides = 4; + const real_t arrow_sides_step = Math_TAU / arrow_sides; for (int k = 0; k < 4; k++) { - Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides); - Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides); + Basis ma(ivec, k * arrow_sides_step); + Basis mb(ivec, (k + 1) * arrow_sides_step); for (int j = 0; j < arrow_points - 1; j++) { Vector3 points[4] = { @@ -5694,8 +5742,11 @@ void Node3DEditor::_init_grid() { return; // Camera3D is invalid, don't draw the grid. } + bool orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL; + Vector<Color> grid_colors[3]; Vector<Vector3> grid_points[3]; + Vector<Vector3> grid_normals[3]; Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color"); Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color"); @@ -5731,10 +5782,26 @@ void Node3DEditor::_init_grid() { int b = (a + 1) % 3; int c = (a + 2) % 3; - real_t division_level = Math::log(Math::abs(camera_position[c])) / Math::log((double)primary_grid_steps) + division_level_bias; - division_level = CLAMP(division_level, division_level_min, division_level_max); - real_t division_level_floored = Math::floor(division_level); - real_t division_level_decimals = division_level - division_level_floored; + Vector3 normal; + normal[c] = 1.0; + + real_t camera_distance = Math::abs(camera_position[c]); + + if (orthogonal) { + camera_distance = camera->get_size() / 2.0; + Vector3 camera_direction = -camera->get_global_transform().get_basis().get_axis(2); + Plane grid_plane = Plane(Vector3(), normal); + Vector3 intersection; + if (grid_plane.intersects_ray(camera_position, camera_direction, &intersection)) { + camera_position = intersection; + } + } + + real_t division_level = Math::log(Math::abs(camera_distance)) / Math::log((double)primary_grid_steps) + division_level_bias; + + real_t clamped_division_level = CLAMP(division_level, division_level_min, division_level_max); + real_t division_level_floored = Math::floor(clamped_division_level); + real_t division_level_decimals = clamped_division_level - division_level_floored; real_t small_step_size = Math::pow(primary_grid_steps, division_level_floored); real_t large_step_size = small_step_size * primary_grid_steps; @@ -5746,6 +5813,15 @@ void Node3DEditor::_init_grid() { real_t bgn_b = center_b - grid_size * small_step_size; real_t end_b = center_b + grid_size * small_step_size; + real_t fade_size = Math::pow(primary_grid_steps, division_level - 1.0); + real_t min_fade_size = Math::pow(primary_grid_steps, float(division_level_min)); + real_t max_fade_size = Math::pow(primary_grid_steps, float(division_level_max)); + fade_size = CLAMP(fade_size, min_fade_size, max_fade_size); + + real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size; + grid_mat[c]->set_shader_param("grid_size", grid_fade_size); + grid_mat[c]->set_shader_param("orthogonal", orthogonal); + // In each iteration of this loop, draw one line in each direction (so two lines per loop, in each if statement). for (int i = -grid_size; i <= grid_size; i++) { Color line_color; @@ -5756,11 +5832,6 @@ void Node3DEditor::_init_grid() { line_color = secondary_grid_color; line_color.a = line_color.a * (1 - division_level_decimals); } - // Makes lines farther from the center fade out. - // Due to limitations of lines, any that come near the camera have full opacity always. - // This should eventually be replaced by some kind of "distance fade" system, outside of this function. - // But the effect is still somewhat convincing... - line_color.a *= 1 - (1 - division_level_decimals * 0.9) * (Math::abs(i / (float)grid_size)); real_t position_a = center_a + i * small_step_size; real_t position_b = center_b + i * small_step_size; @@ -5777,6 +5848,8 @@ void Node3DEditor::_init_grid() { grid_points[c].push_back(line_end); grid_colors[c].push_back(line_color); grid_colors[c].push_back(line_color); + grid_normals[c].push_back(normal); + grid_normals[c].push_back(normal); } if (!(origin_enabled && Math::is_zero_approx(position_b))) { @@ -5790,6 +5863,8 @@ void Node3DEditor::_init_grid() { grid_points[c].push_back(line_end); grid_colors[c].push_back(line_color); grid_colors[c].push_back(line_color); + grid_normals[c].push_back(normal); + grid_normals[c].push_back(normal); } } @@ -5799,8 +5874,9 @@ void Node3DEditor::_init_grid() { d.resize(RS::ARRAY_MAX); d[RenderingServer::ARRAY_VERTEX] = grid_points[c]; d[RenderingServer::ARRAY_COLOR] = grid_colors[c]; + d[RenderingServer::ARRAY_NORMAL] = grid_normals[c]; RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[c], RenderingServer::PRIMITIVE_LINES, d); - RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, indicator_mat->get_rid()); + RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, grid_mat[c]->get_rid()); grid_instance[c] = RenderingServer::get_singleton()->instance_create2(grid[c], get_tree()->get_root()->get_world_3d()->get_scenario()); // Yes, the end of this line is supposed to be a. diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index d7a47fa4fa..9fb7488a0f 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -590,7 +590,6 @@ private: ///// ToolMode tool_mode; - bool orthogonal; RenderingServer::ScenarioDebugMode scenario_debug; @@ -623,6 +622,7 @@ private: RID cursor_mesh; RID cursor_instance; Ref<StandardMaterial3D> indicator_mat; + Ref<ShaderMaterial> grid_mat[3]; Ref<StandardMaterial3D> cursor_material; // Scene drag and drop support diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 1f20a87565..0a949c8610 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -42,7 +42,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, // These properties are translated with the tr() function in the C++ code when being set or updated. Error err; - RES loaded_res = ResourceLoader::load(p_path, "PackedScene", false, &err); + RES loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 216c0c3bef..a6afd45686 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -894,7 +894,7 @@ void ScriptEditor::_reload_scripts() { Ref<Script> script = edited_res; if (script != nullptr) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index f57c8fbd6b..71b18497b0 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -688,7 +688,7 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo uint64_t date = FileAccess::get_modified_time(script->get_path()); if (last_date != date) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 05a1561f7d..8be82628cb 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -405,7 +405,7 @@ void ShaderEditor::_check_for_external_edit() { } void ShaderEditor::_reload_shader_from_disk() { - Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), true); + Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_FAIL_COND(!rel_shader.is_valid()); shader->set_code(rel_shader->get_code()); diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 04e6aa6fa8..36297c8a4a 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -57,7 +57,7 @@ void Texture3DEditor::_notification(int p_what) { } } -void Texture3DEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void Texture3DEditor::_texture_changed() { if (!is_visible()) { return; } @@ -118,7 +118,7 @@ void Texture3DEditor::_texture_rect_update_area() { void Texture3DEditor::edit(Ref<Texture3D> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); } texture = p_texture; @@ -128,7 +128,7 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) { _make_shaders(); } - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); update(); texture_rect->set_material(material); setting = true; @@ -184,7 +184,7 @@ Texture3DEditor::Texture3DEditor() { Texture3DEditor::~Texture3DEditor() { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed)); } } diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h index 944abf16d9..9d90d3653f 100644 --- a/editor/plugins/texture_3d_editor_plugin.h +++ b/editor/plugins/texture_3d_editor_plugin.h @@ -61,10 +61,12 @@ class Texture3DEditor : public Control { void _texture_rect_update_area(); void _texture_rect_draw(); + void _texture_changed(); + protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; + static void _bind_methods(); public: diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 1d3fd668c6..253f8878d2 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -104,7 +104,7 @@ void TextureEditor::_notification(int p_what) { } } -void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureEditor::_texture_changed() { if (!is_visible()) { return; } @@ -113,13 +113,13 @@ void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { void TextureEditor::edit(Ref<Texture2D> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed)); } texture = p_texture; if (!texture.is_null()) { - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &TextureEditor::_texture_changed)); update(); } else { hide(); @@ -137,7 +137,7 @@ TextureEditor::TextureEditor() { TextureEditor::~TextureEditor() { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed)); } } diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 621d737028..ebe8882194 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -43,7 +43,7 @@ class TextureEditor : public Control { protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; + void _texture_changed(); static void _bind_methods(); public: diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 2be300ad66..254ad3d56e 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -63,7 +63,7 @@ void TextureLayeredEditor::_notification(int p_what) { } } -void TextureLayeredEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureLayeredEditor::_texture_changed() { if (!is_visible()) { return; } @@ -173,7 +173,7 @@ void TextureLayeredEditor::_texture_rect_update_area() { void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { if (!texture.is_null()) { - texture->remove_change_receptor(this); + texture->disconnect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); } texture = p_texture; @@ -183,7 +183,7 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) { _make_shaders(); } - texture->add_change_receptor(this); + texture->connect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed)); update(); texture_rect->set_material(materials[texture->get_layered_type()]); setting = true; @@ -248,9 +248,6 @@ TextureLayeredEditor::TextureLayeredEditor() { } TextureLayeredEditor::~TextureLayeredEditor() { - if (!texture.is_null()) { - texture->remove_change_receptor(this); - } } // diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h index 4bcc8fa1f1..c4ced62fb9 100644 --- a/editor/plugins/texture_layered_editor_plugin.h +++ b/editor/plugins/texture_layered_editor_plugin.h @@ -63,10 +63,11 @@ class TextureLayeredEditor : public Control { void _texture_rect_update_area(); void _texture_rect_draw(); + void _texture_changed(); + protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); - void _changed_callback(Object *p_changed, const char *p_prop) override; static void _bind_methods(); public: diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 61e0cc281d..63255e6547 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -480,20 +480,41 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom); hscroll->set_value(hscroll->get_value() - dragged.x); vscroll->set_value(vscroll->get_value() - dragged.y); - } else if (drag) { if (edited_margin >= 0) { float new_margin = 0; - if (edited_margin == 0) { - new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom; - } else if (edited_margin == 1) { - new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom; - } else if (edited_margin == 2) { - new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom; - } else if (edited_margin == 3) { - new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom; + + if (snap_mode != SNAP_GRID) { + if (edited_margin == 0) { + new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom; + } else if (edited_margin == 1) { + new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom; + } else if (edited_margin == 2) { + new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom; + } else if (edited_margin == 3) { + new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom; + } else { + ERR_PRINT("Unexpected edited_margin"); + } + + if (snap_mode == SNAP_PIXEL) { + new_margin = Math::round(new_margin); + } } else { - ERR_PRINT("Unexpected edited_margin"); + Vector2 pos_snapped = snap_point(mtx.affine_inverse().xform(mm->get_position())); + Rect2 rect_rounded = Rect2(rect.position.round(), rect.size.round()); + + if (edited_margin == 0) { + new_margin = pos_snapped.y - rect_rounded.position.y; + } else if (edited_margin == 1) { + new_margin = rect_rounded.size.y + rect_rounded.position.y - pos_snapped.y; + } else if (edited_margin == 2) { + new_margin = pos_snapped.x - rect_rounded.position.x; + } else if (edited_margin == 3) { + new_margin = rect_rounded.size.x + rect_rounded.position.x - pos_snapped.x; + } else { + ERR_PRINT("Unexpected edited_margin"); + } } if (new_margin < 0) { @@ -842,19 +863,19 @@ Sprite2D *TextureRegionEditor::get_sprite() { void TextureRegionEditor::edit(Object *p_obj) { if (node_sprite) { - node_sprite->remove_change_receptor(this); + node_sprite->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_sprite_3d) { - node_sprite_3d->remove_change_receptor(this); + node_sprite_3d->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_ninepatch) { - node_ninepatch->remove_change_receptor(this); + node_ninepatch->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (obj_styleBox.is_valid()) { - obj_styleBox->remove_change_receptor(this); + obj_styleBox->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (atlas_tex.is_valid()) { - atlas_tex->remove_change_receptor(this); + atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (p_obj) { node_sprite = Object::cast_to<Sprite2D>(p_obj); @@ -866,7 +887,7 @@ void TextureRegionEditor::edit(Object *p_obj) { if (Object::cast_to<AtlasTexture>(p_obj)) { atlas_tex = Ref<AtlasTexture>(Object::cast_to<AtlasTexture>(p_obj)); } - p_obj->add_change_receptor(this); + p_obj->connect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); _edit_region(); } else { node_sprite = nullptr; @@ -884,14 +905,11 @@ void TextureRegionEditor::edit(Object *p_obj) { } } -void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) { +void TextureRegionEditor::_texture_changed() { if (!is_visible()) { return; } - String prop = p_prop; - if (prop == "atlas" || prop == "texture" || prop == "region") { - _edit_region(); - } + _edit_region(); } void TextureRegionEditor::_edit_region() { diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index 56ccefb025..d3db0a08a9 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -117,6 +117,8 @@ class TextureRegionEditor : public VBoxContainer { void _update_rect(); void _update_autoslice(); + void _texture_changed(); + protected: void _notification(int p_what); void _node_removed(Object *p_obj); @@ -124,8 +126,6 @@ protected: Vector2 snap_point(Vector2 p_target) const; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; - public: void _edit_region(); void _region_draw(); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index deeab2fbc7..c628fe8367 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -39,7 +39,6 @@ void TileSetEditor::edit(const Ref<TileSet> &p_tileset) { tileset = p_tileset; - tileset->add_change_receptor(this); texture_list->clear(); texture_map.clear(); @@ -1859,7 +1858,7 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { _update_toggle_shape_button(); workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } else if (p_tool == SELECT_NEXT) { _select_next_shape(); @@ -2173,7 +2172,7 @@ Array TileSetEditor::_get_tiles_in_current_texture(bool sorted) { } } if (sorted) { - a.sort_custom(this, "_sort_tiles"); + a.sort_custom(callable_mp(this, &TileSetEditor::_sort_tiles)); } return a; } @@ -2287,7 +2286,7 @@ void TileSetEditor::_select_next_shape() { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } @@ -2349,7 +2348,7 @@ void TileSetEditor::_select_previous_shape() { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } } @@ -3012,7 +3011,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { undo_redo->add_undo_method(this, "_select_edited_shape_coord"); undo_redo->commit_action(); } - tileset->_change_notify(""); + tileset->notify_property_list_changed(); } void TileSetEditor::select_coord(const Vector2 &coord) { @@ -3115,7 +3114,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) { } workspace->update(); workspace_container->update(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } Vector2 TileSetEditor::snap_point(const Vector2 &point) { @@ -3225,7 +3224,7 @@ void TileSetEditor::update_texture_list() { workspace_overlay->update(); } update_texture_list_icon(); - helper->_change_notify(""); + helper->notify_property_list_changed(); } void TileSetEditor::update_texture_list_icon() { @@ -3389,7 +3388,7 @@ int TileSetEditor::get_current_tile() const { void TileSetEditor::set_current_tile(int p_id) { if (current_tile != p_id) { current_tile = p_id; - helper->_change_notify(""); + helper->notify_property_list_changed(); select_coord(Vector2(0, 0)); update_workspace_tile_mode(); if (p_id == -1) { @@ -3414,7 +3413,7 @@ void TilesetEditorContext::set_tileset(const Ref<TileSet> &p_tileset) { void TilesetEditorContext::set_snap_options_visible(bool p_visible) { snap_options_visible = p_visible; - _change_notify(""); + notify_property_list_changed(); } bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value) { @@ -3450,7 +3449,7 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/" + name2, p_value, &v); } if (v) { - tileset->_change_notify(""); + tileset->notify_property_list_changed(); tileset_editor->workspace->update(); tileset_editor->workspace_overlay->update(); } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index fb821a0856..5061067ded 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1737,114 +1737,220 @@ void VisualShaderEditor::_add_curve_node(const String &p_path) { curve->set_texture(ResourceLoader::load(p_path)); } -VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { - ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); +void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { + // FLOAT_OP + { + VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(p_node); - Ref<VisualShaderNode> vsnode; + if (floatOp) { + floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); + return; + } + } - bool is_custom = add_options[p_idx].is_custom; + // FLOAT_FUNC + { + VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(p_node); - if (!is_custom && add_options[p_idx].type != String()) { - VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); - ERR_FAIL_COND_V(!vsn, nullptr); + if (floatFunc) { + floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); + // VECTOR_OP + { + VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(p_node); - if (constant) { - if ((int)add_options[p_idx].value != -1) { - constant->set_constant(add_options[p_idx].value); - } + if (vecOp) { + vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx); + return; } + } - if (p_op_idx != -1) { - VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn); + // VECTOR_FUNC + { + VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(p_node); - if (input) { - input->set_input_name(add_options[p_idx].sub_func_str); - } + if (vecFunc) { + vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(vsn); + // COLOR_OP + { + VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(p_node); - if (is) { - is->set_function((VisualShaderNodeIs::Function)p_op_idx); - } + if (colorOp) { + colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx); + return; + } + } - VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(vsn); + // COLOR_FUNC + { + VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(p_node); - if (cmp) { - cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); - } + if (colorFunc) { + colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(vsn); + // INT_OP + { + VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(p_node); - if (colorOp) { - colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx); - } + if (intOp) { + intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); + return; + } + } - VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(vsn); + // INT_FUNC + { + VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(p_node); - if (colorFunc) { - colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); - } + if (intFunc) { + intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(vsn); + // TRANSFORM_FUNC + { + VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(p_node); - if (floatOp) { - floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); - } + if (matFunc) { + matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(vsn); + // IS + { + VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node); - if (intOp) { - intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); - } + if (is) { + is->set_function((VisualShaderNodeIs::Function)p_op_idx); + return; + } + } - VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(vsn); + // COMPARE + { + VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(p_node); - if (floatFunc) { - floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); - } + if (cmp) { + cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); + return; + } + } - VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(vsn); + // DERIVATIVE + { + VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(p_node); - if (intFunc) { - intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); - } + if (sderFunc) { + sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx); + return; + } - VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(vsn); + VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(p_node); - if (vecOp) { - vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx); - } + if (vderFunc) { + vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx); + return; + } + } - VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(vsn); + // MIX + { + VisualShaderNodeMix *mix = Object::cast_to<VisualShaderNodeMix>(p_node); - if (vecFunc) { - vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx); - } + if (mix) { + mix->set_op_type((VisualShaderNodeMix::OpType)p_op_idx); + return; + } + } - VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(vsn); + // CLAMP + { + VisualShaderNodeClamp *clampFunc = Object::cast_to<VisualShaderNodeClamp>(p_node); - if (matFunc) { - matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx); - } + if (clampFunc) { + clampFunc->set_op_type((VisualShaderNodeClamp::OpType)p_op_idx); + return; + } + } - VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(vsn); + // SWITCH + { + VisualShaderNodeSwitch *switchFunc = Object::cast_to<VisualShaderNodeSwitch>(p_node); - if (sderFunc) { - sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx); - } + if (switchFunc) { + switchFunc->set_op_type((VisualShaderNodeSwitch::OpType)p_op_idx); + return; + } + } - VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(vsn); + // SMOOTHSTEP + { + VisualShaderNodeSmoothStep *smoothStepFunc = Object::cast_to<VisualShaderNodeSmoothStep>(p_node); - if (vderFunc) { - vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx); - } + if (smoothStepFunc) { + smoothStepFunc->set_op_type((VisualShaderNodeSmoothStep::OpType)p_op_idx); + return; + } + } + + // STEP + { + VisualShaderNodeStep *stepFunc = Object::cast_to<VisualShaderNodeStep>(p_node); + + if (stepFunc) { + stepFunc->set_op_type((VisualShaderNodeStep::OpType)p_op_idx); + return; + } + } + + // MULTIPLY_ADD + { + VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(p_node); + + if (fmaFunc) { + fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx); + } + } +} - VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(vsn); +VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { + ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); + + Ref<VisualShaderNode> vsnode; + + bool is_custom = add_options[p_idx].is_custom; - if (fmaFunc) { - fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx); + if (!is_custom && add_options[p_idx].type != String()) { + VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); + ERR_FAIL_COND_V(!vsn, nullptr); + + VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); + + if (constant) { + if ((int)add_options[p_idx].value != -1) { + constant->set_constant(add_options[p_idx].value); + } + } else { + if (p_op_idx != -1) { + VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn); + + if (input) { + input->set_input_name(add_options[p_idx].sub_func_str); + } else { + _setup_node(vsn, p_op_idx); + } } } @@ -1923,11 +2029,22 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { int _from_node = id_to_use; int _from_slot = 0; - if (created_expression_port || visual_shader->is_port_types_compatible(vsnode->get_output_port_type(_from_slot), input_port_type)) { + if (created_expression_port) { undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot); + } else { + // Attempting to connect to the first correct port. + for (int i = 0; i < vsnode->get_output_port_count(); i++) { + if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type)) { + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot); + break; + } + } } } } else if (from_node != -1 && from_slot != -1) { @@ -1945,11 +2062,22 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { int _to_node = id_to_use; int _to_slot = 0; - if (created_expression_port || visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(_to_slot))) { + if (created_expression_port) { undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot); undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot); + } else { + // Attempting to connect to the first correct port. + for (int i = 0; i < vsnode->get_input_port_count(); i++) { + if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) { + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i); + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i); + break; + } + } } } } @@ -3446,8 +3574,11 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); - add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SwitchS", "Conditional", "Functions", "VisualShaderNodeScalarSwitch", TTR("Returns an associated scalar if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SwitchInt", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("SwitchTransform", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); @@ -3670,8 +3801,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeScalarClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Constrains a value to lie between two further values."), VisualShaderNodeIntFunc::FUNC_CLAMP, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeFloatFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -3684,7 +3815,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), VisualShaderNodeFloatOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), VisualShaderNodeFloatOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeScalarInterp", TTR("Linear interpolation between two scalars."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), VisualShaderNodeMix::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("MultiplyAdd", "Scalar", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeFloatFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeIntFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR_INT)); @@ -3700,8 +3831,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeFloatOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeFloatFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -3785,7 +3916,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeVectorClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -3803,8 +3934,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeVectorInterp", TTR("Linear interpolation between two vectors."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeVectorScalarMix", TTR("Linear interpolation between two vectors using scalar."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), VisualShaderNodeMix::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), VisualShaderNodeMix::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -3821,10 +3952,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -4342,10 +4473,17 @@ void VisualShaderNodePortPreview::_shader_changed() { for (int i = EditorNode::get_singleton()->get_editor_history()->get_path_size() - 1; i >= 0; i--) { Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(i)); + ShaderMaterial *src_mat; if (!object) { continue; } - ShaderMaterial *src_mat = Object::cast_to<ShaderMaterial>(object); + if (object->has_method("get_material_override")) { // trying getting material from MeshInstance + src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material_override")); + } else if (object->has_method("get_material")) { // from CanvasItem/Node2D + src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material")); + } else { + src_mat = Object::cast_to<ShaderMaterial>(object); + } if (src_mat && src_mat->get_shader().is_valid()) { List<PropertyInfo> params; src_mat->get_shader()->get_param_list(¶ms); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 72ed46b35c..182bed6ba6 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -276,6 +276,7 @@ class VisualShaderEditor : public VBoxContainer { void _add_texture3d_node(const String &p_path); void _add_curve_node(const String &p_path); + void _setup_node(VisualShaderNode *p_node, int p_op_idx); VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1); void _update_options_menu(); void _set_mode(int p_which); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index e46b2711c1..4667d80057 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1375,11 +1375,10 @@ void ProjectList::create_project_item_control(int p_index) { vb->add_child(path_hb); Button *show = memnew(Button); - // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't + // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't. show->set_icon(get_theme_icon(!item.missing ? "Load" : "FileBroken", "EditorIcons")); - show->set_flat(true); if (!item.grayed) { - // Don't make the icon less prominent if the parent is already grayed out + // Don't make the icon less prominent if the parent is already grayed out. show->set_modulate(Color(1, 1, 1, 0.5)); } path_hb->add_child(show); @@ -2016,6 +2015,10 @@ void ProjectManager::_confirm_update_settings() { } void ProjectManager::_open_selected_projects() { + // Show loading text to tell the user that the project manager is busy loading. + // This is especially important for the HTML5 project manager. + loading_label->set_modulate(Color(1, 1, 1)); + const Set<String> &selected_list = _project_list->get_selected_project_keys(); for (const Set<String>::Element *E = selected_list.front(); E; E = E->next()) { @@ -2158,8 +2161,9 @@ void ProjectManager::_run_project() { } void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { - DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->change_dir(path); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Error error = da->change_dir(path); + ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path); da->list_dir_begin(); String n = da->get_next(); while (n != String()) { @@ -2171,7 +2175,6 @@ void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { n = da->get_next(); } da->list_dir_end(); - memdelete(da); } void ProjectManager::_scan_begin(const String &p_base) { @@ -2269,11 +2272,6 @@ void ProjectManager::_restart_confirm() { get_tree()->quit(); } -void ProjectManager::_exit_dialog() { - _dim_window(); - get_tree()->quit(); -} - void ProjectManager::_install_project(const String &p_zip_path, const String &p_title) { npdialog->set_mode(ProjectDialog::MODE_INSTALL); npdialog->set_zip_path(p_zip_path); @@ -2282,6 +2280,11 @@ void ProjectManager::_install_project(const String &p_zip_path, const String &p_ } void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) { + if (p_files.size() == 1 && p_files[0].ends_with(".zip")) { + const String file = p_files[0].get_file(); + _install_project(p_files[0], file.substr(0, file.length() - 4).capitalize()); + return; + } Set<String> folders_set; DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < p_files.size(); i++) { @@ -2347,7 +2350,6 @@ void ProjectManager::_on_search_term_changed(const String &p_term) { } void ProjectManager::_bind_methods() { - ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog); ClassDB::bind_method("_unhandled_key_input", &ProjectManager::_unhandled_key_input); ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons); } @@ -2477,7 +2479,12 @@ ProjectManager::ProjectManager() { search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); hb->add_child(search_box); - hb->add_spacer(); + loading_label = memnew(Label(TTR("Loading, please wait..."))); + loading_label->add_theme_font_override("font", get_theme_font("bold", "EditorFonts")); + loading_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + hb->add_child(loading_label); + // Hide the label but make it still take up space. This prevents reflows when showing the label. + loading_label->set_modulate(Color(0, 0, 0, 0)); Label *sort_label = memnew(Label); sort_label->set_text(TTR("Sort:")); @@ -2684,8 +2691,26 @@ ProjectManager::ProjectManager() { _load_recent_projects(); - if (EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path")) { - _scan_begin(EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path")); + DirAccessRef dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM); + + String default_project_path = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path"); + if (!dir_access->dir_exists(default_project_path)) { + Error error = dir_access->make_dir_recursive(default_project_path); + if (error != OK) { + ERR_PRINT("Could not create default project directory at: " + default_project_path); + } + } + + String autoscan_path = EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"); + if (autoscan_path != "") { + if (dir_access->dir_exists(autoscan_path)) { + _scan_begin(autoscan_path); + } else { + Error error = dir_access->make_dir_recursive(autoscan_path); + if (error != OK) { + ERR_PRINT("Could not create project autoscan directory at: " + autoscan_path); + } + } } SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped)); diff --git a/editor/project_manager.h b/editor/project_manager.h index db8cb8410c..6dc0e67cba 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -54,6 +54,7 @@ class ProjectManager : public Control { ProjectList *_project_list; LineEdit *search_box; + Label *loading_label; OptionButton *filter_option; Button *run_btn; @@ -98,7 +99,6 @@ class ProjectManager : public Control { void _update_project_buttons(); void _language_selected(int p_id); void _restart_confirm(); - void _exit_dialog(); void _confirm_update_settings(); void _nonempty_confirmation_ok_pressed(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index ac1beb1c37..11f44720da 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2841,7 +2841,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel filter->set_h_size_flags(SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter nodes")); filter_hbc->add_child(filter); - filter->add_theme_constant_override("minimum_spaces", 0); + filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed)); button_create_script = memnew(Button); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index b8475656ee..2cd64a81dc 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -156,7 +156,7 @@ void SceneTreeEditor::_toggle_visible(Node *p_node) { } } -bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { +bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected) { if (!p_node) { return false; } @@ -391,15 +391,19 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } } + bool scroll = false; + if (editor_selection) { if (editor_selection->is_selected(p_node)) { item->select(0); + scroll = p_scroll_to_selected; } } if (selected == p_node) { if (!editor_selection) { item->select(0); + scroll = p_scroll_to_selected; } item->set_as_cursor(0); } @@ -407,7 +411,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { bool keep = (filter.is_subsequence_ofi(String(p_node->get_name()))); for (int i = 0; i < p_node->get_child_count(); i++) { - bool child_keep = _add_nodes(p_node->get_child(i), item); + bool child_keep = _add_nodes(p_node->get_child(i), item, p_scroll_to_selected); keep = keep || child_keep; } @@ -438,6 +442,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { memdelete(item); return false; } else { + if (scroll) { + tree->scroll_to_item(item); + } return true; } } @@ -525,7 +532,7 @@ void SceneTreeEditor::_node_renamed(Node *p_node) { } } -void SceneTreeEditor::_update_tree() { +void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) { if (!is_inside_tree()) { tree_dirty = false; return; @@ -534,7 +541,7 @@ void SceneTreeEditor::_update_tree() { updating_tree = true; tree->clear(); if (get_scene_node()) { - _add_nodes(get_scene_node(), nullptr); + _add_nodes(get_scene_node(), nullptr, p_scroll_to_selected); last_hash = hash_djb2_one_64(0); _compute_hash(get_scene_node(), last_hash); } @@ -817,7 +824,7 @@ void SceneTreeEditor::set_marked(Node *p_marked, bool p_selectable, bool p_child void SceneTreeEditor::set_filter(const String &p_filter) { filter = p_filter; - _update_tree(); + _update_tree(true); } String SceneTreeEditor::get_filter() const { @@ -1253,7 +1260,7 @@ SceneTreeDialog::SceneTreeDialog() { filter = memnew(LineEdit); filter->set_h_size_flags(Control::SIZE_EXPAND_FILL); filter->set_placeholder(TTR("Filter nodes")); - filter->add_theme_constant_override("minimum_spaces", 0); + filter->add_theme_constant_override("minimum_character_width", 0); filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed)); vbc->add_child(filter); diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 831723a27c..7d3419516d 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -71,9 +71,9 @@ class SceneTreeEditor : public Control { void _compute_hash(Node *p_node, uint64_t &hash); - bool _add_nodes(Node *p_node, TreeItem *p_parent); + bool _add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected = false); void _test_update_tree(); - void _update_tree(); + void _update_tree(bool p_scroll_to_selected = false); void _tree_changed(); void _node_removed(Node *p_node); void _node_renamed(Node *p_node); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 14d305e34f..a61b4aa3b9 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -427,7 +427,7 @@ void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { void ShaderGlobalsEditor::_changed() { emit_signal("globals_changed"); if (!interface->block_update) { - interface->_change_notify(); + interface->notify_property_list_changed(); } } diff --git a/editor/translations/af.po b/editor/translations/af.po index 5caef149fa..c537e790e7 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -7402,6 +7402,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 2cfe1ac76c..7af493c55a 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -7335,6 +7335,11 @@ msgid "Yaw" msgstr "Ø§Ù„Ø¥Ù†ØØ±Ø§Ù Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Ø§Ù„ØØ¬Ù…: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "كائنات مرسومة" diff --git a/editor/translations/bg.po b/editor/translations/bg.po index fd7a8f4332..b03e325ec5 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-22 10:21+0000\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" "Last-Translator: Любомир ВаÑилев <lyubomirv@gmx.com>\n" "Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/" "godot/bg/>\n" @@ -2232,11 +2232,11 @@ msgstr "" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "" +msgstr "Ðе може да Ñе зареди библиотеката Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи за Ñливане!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "" +msgstr "Грешка при запазването на библиотеката Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" @@ -2359,7 +2359,7 @@ msgstr "ОперациÑта не може да Ñе извърши без ÑцР#: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "ИзнаÑÑне на библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." @@ -2641,7 +2641,7 @@ msgstr "" #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи…" #: editor/editor_node.cpp msgid "TileSet..." @@ -2758,6 +2758,8 @@ msgid "" "When this option is enabled, navigation meshes and polygons will be visible " "in the running project." msgstr "" +"Ðко тази наÑтройка е включено, навигационните полигони и мрежи ще бъдат " +"видими в изпълнÑÐ²Ð°Ñ‰Ð¸Ñ Ñе проект." #: editor/editor_node.cpp msgid "Synchronize Scene Changes" @@ -3855,7 +3857,7 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "Създаване за полигонна мрежа: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -4339,7 +4341,7 @@ msgstr "Ðово име на анимациÑта:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Ðова анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" @@ -4353,20 +4355,20 @@ msgstr "Изтриване на анимациÑта?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Премахване на анимациÑта" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Invalid animation name!" -msgstr "" +msgstr "Ðеправилно име на анимациÑта!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation name already exists!" -msgstr "" +msgstr "Вече ÑъщеÑтвува Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ñ Ñ‚Ð¾Ð²Ð° име!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "Преименуване на анимациÑта" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" @@ -4374,19 +4376,19 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "" +msgstr "ПромÑна на времето на ÑмеÑване" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "Зареждане на анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Дублиране на анимациÑта" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to copy!" -msgstr "" +msgstr "ÐÑма Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° копиране!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation resource on clipboard!" @@ -4394,11 +4396,11 @@ msgstr "ÐÑма реÑурÑâ€“Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð² буфера за обмен #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "" +msgstr "ПоÑтавена анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "" +msgstr "ПоÑтавÑне на анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to edit!" @@ -4407,30 +4409,32 @@ msgstr "ÐÑма Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° редактиране!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" msgstr "" +"Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ от текущата позициÑ. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ от краÑ. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "Спиране на възпроизвеждането на анимациÑта. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ началото. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ текущата позициÑ. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð² анимациÑта (в Ñекунди)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." msgstr "" +"Скалиране на ÑкороÑтта на възпроизвеждане на анимациÑта глобално за възела." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" @@ -4438,7 +4442,7 @@ msgstr "ИнÑтрументи за анимациите" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "ÐнимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -4446,7 +4450,7 @@ msgstr "Редактиране на преходите..." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Open in Inspector" -msgstr "" +msgstr "ОтварÑне в инÑпектора" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." @@ -4454,15 +4458,15 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Ðвт. възпроизвеждане при зареждане" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "Показване на избледнÑващи кадри" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning Options" -msgstr "" +msgstr "ÐаÑтройки на режима Ñ Ð¸Ð·Ð±Ð»ÐµÐ´Ð½Ñващи кадри" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4510,11 +4514,11 @@ msgstr "Закачане на AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Създаване на нова анимациÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Име на анимациÑта:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp @@ -4525,15 +4529,15 @@ msgstr "Грешка!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "" +msgstr "Времена на ÑмеÑване:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "" +msgstr "Следваща (авт. опашка):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" -msgstr "" +msgstr "Времена на ÑмеÑване между анимациите" #: editor/plugins/animation_state_machine_editor.cpp msgid "Move Node" @@ -4550,23 +4554,23 @@ msgstr "ДобавÑне на преход" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "" +msgstr "ДобавÑне на възел" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "" +msgstr "Край" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "Ðезабавно" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "Синхронизиране" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" -msgstr "" +msgstr "Ðа краÑ" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" @@ -5461,7 +5465,7 @@ msgstr "Преглед" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Always Show Grid" -msgstr "" +msgstr "Винаги да Ñе показва решетката" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" @@ -5469,7 +5473,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Rulers" -msgstr "" +msgstr "Показване на линиите" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Guides" @@ -5668,12 +5672,12 @@ msgstr "" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "" +msgstr "Създаване на излъчващи точки от полигонната мрежа" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "" +msgstr "Създаване на излъчващи точки от възела" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 0" @@ -5770,7 +5774,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "" +msgstr "Полигонната мрежа е празна!" #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5815,19 +5819,21 @@ msgstr "Създаване на нÑколко изпъкнали форми" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "" +msgstr "Създаване на навигационна полигонна мрежа" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "Съдържащата Ñе полигонна мрежа не е от тип ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" msgstr "" +"Разгъването на UV беше неуÑпешно. Възможно ли е полигонната мрежа да Ñе " +"ÑÑŠÑтои от повече от една форма?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." -msgstr "" +msgstr "ÐÑма полигонна мрежа за дебъгване." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Model has no UV in this layer" @@ -5835,15 +5841,15 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "" +msgstr "Ð’ MeshInstance нÑма полигонна мрежа!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" -msgstr "" +msgstr "Полигонната мрежа нÑма повърхноÑÑ‚, от коÑто да Ñе Ñъздадат контури!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "" +msgstr "ПримитивниÑÑ‚ тип на полигонната мрежа не е PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" @@ -5855,7 +5861,7 @@ msgstr "Създаване на контур" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "" +msgstr "Полигонна мрежа" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" @@ -5902,7 +5908,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." -msgstr "" +msgstr "Създаване на контурна полигонна мрежа…" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -5911,6 +5917,10 @@ msgid "" "This can be used instead of the SpatialMaterial Grow property when using " "that property isn't possible." msgstr "" +"Създава Ñтатична полигонна мрежа за контура. Ðормалите на контурната " +"полигонна мрежа ще бъдат автоматично обърнати.\n" +"Това може да Ñе използва вмеÑто ÑвойÑтвото Grow на SpatialMaterial, когато " +"това ÑвойÑтво не може да Ñе променÑ." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" @@ -5926,7 +5936,7 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "" +msgstr "Създаване на контурна полигонна мрежа" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" @@ -5950,7 +5960,7 @@ msgstr "" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Mesh Library" -msgstr "Библиотека от полигонни мрежи" +msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи" #: editor/plugins/mesh_library_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -5972,22 +5982,27 @@ msgstr "ОбновÑване от Ñцена" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." msgstr "" +"ÐÑма поÑочен източник за полигонна мрежа (и във възела нÑма MultiMesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." msgstr "" +"ÐÑма поÑочен източник за полигонна мрежа (и MultiMesh не Ñъдържа полигонна " +"мрежа)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "" +msgstr "Източникът за полигонна мрежа е неправилен (грешен път)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "" +msgstr "Източникът за полигонна мрежа е неправилен (не е MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." msgstr "" +"Източникът за полигонна мрежа е неправилен (не Ñъдържа реÑурÑ, който е " +"полигонна мрежа)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." @@ -6007,7 +6022,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "" +msgstr "Изберете източник за полигонна мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" @@ -6027,7 +6042,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" -msgstr "" +msgstr "Източник за полигонна мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" @@ -6043,7 +6058,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" -msgstr "" +msgstr "ÐžÑ Ñочеща нагоре за полигонната мрежа:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Rotation:" @@ -6118,15 +6133,15 @@ msgstr "" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Points:" -msgstr "" +msgstr "Излъчващи точки:" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points" -msgstr "" +msgstr "Точки на повърхноÑтта" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points+Normal (Directed)" -msgstr "" +msgstr "Точки на повърхноÑтта + нормали (наÑочени)" #: editor/plugins/particles_editor_plugin.cpp msgid "Volume" @@ -6134,7 +6149,7 @@ msgstr "Обем" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Source: " -msgstr "" +msgstr "Източник на излъчването: " #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -7108,6 +7123,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" @@ -7533,11 +7552,11 @@ msgstr "" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." -msgstr "" +msgstr "Ðеправилна геометриÑ. Ðе може да Ñе замени Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð° мрежа." #: editor/plugins/sprite_editor_plugin.cpp msgid "Convert to Mesh2D" -msgstr "" +msgstr "Преобразуване в Mesh2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11156,6 +11175,8 @@ msgstr "Филтриране на полигонните мрежи" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "" +"Задайте реÑÑƒÑ€Ñ Ð¾Ñ‚ тип MeshLibrary в този GridMap, за да можете да използвате " +"полигонните му мрежи." #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Begin Bake" @@ -11196,11 +11217,11 @@ msgstr "" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Bake NavMesh" -msgstr "" +msgstr "Изпичане на NavMesh" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "" +msgstr "ИзчиÑтване на навигационната полигонна мрежа." #: modules/recast/navigation_mesh_generator.cpp msgid "Setting up Configuration..." @@ -11236,15 +11257,15 @@ msgstr "" #: modules/recast/navigation_mesh_generator.cpp msgid "Creating polymesh..." -msgstr "" +msgstr "Създаване на полигонна мрежа…" #: modules/recast/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." -msgstr "" +msgstr "Преобразуване на навигационната полигонна мрежа в ÑобÑÑ‚Ð²ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚â€¦" #: modules/recast/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "" +msgstr "ÐаÑтройка на генератора на навигационни полигонни мрежи:" #: modules/recast/navigation_mesh_generator.cpp msgid "Parsing Geometry..." @@ -12147,7 +12168,7 @@ msgstr "" #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" -msgstr "" +msgstr "ТърÑене на полигонни мрежи и Ñветлини" #: scene/3d/baked_lightmap.cpp msgid "Preparing geometry (%d/%d)" @@ -12215,7 +12236,7 @@ msgstr "" #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." -msgstr "" +msgstr "Ðе Ñе вижда нищо, той като нÑма зададена полигонна мрежа." #: scene/3d/cpu_particles.cpp msgid "" @@ -12225,7 +12246,7 @@ msgstr "" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" -msgstr "" +msgstr "ПоÑтроÑване на полигонните мрежи" #: scene/3d/gi_probe.cpp msgid "Finishing Plot" @@ -12249,12 +12270,16 @@ msgstr "" #: scene/3d/navigation_mesh.cpp msgid "A NavigationMesh resource must be set or created for this node to work." msgstr "" +"ТрÑбва да Ñе зададе или Ñъздаде реÑÑƒÑ€Ñ Ð¾Ñ‚ тип NavigationMesh, за може да " +"работи този възел." #: scene/3d/navigation_mesh.cpp msgid "" "NavigationMeshInstance must be a child or grandchild to a Navigation node. " "It only provides navigation data." msgstr "" +"NavigationMeshInstance трÑбва да бъде дъщерен или под-дъщерен на възел от " +"тип Navigation. Той Ñамо предоÑÑ‚Ð°Ð²Ñ Ð´Ð°Ð½Ð½Ð¸Ñ‚Ðµ за навигирането." #: scene/3d/particles.cpp msgid "" @@ -12267,6 +12292,8 @@ msgstr "" msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" +"Ðе Ñе вижда нищо, тъй като полигонните мрежи не Ñа били Ñвързани към Ñтъпки " +"на изчертаване." #: scene/3d/particles.cpp msgid "" @@ -12321,7 +12348,7 @@ msgstr "" #: scene/3d/soft_body.cpp msgid "This body will be ignored until you set a mesh." -msgstr "" +msgstr "Това Ñ‚Ñло ще бъде игнорирано, докато не зададете полигонна мрежа." #: scene/3d/soft_body.cpp msgid "" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index 4482328985..53a1d59aa3 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -8,14 +8,14 @@ # Tawhid H. <Tawhidk757@yahoo.com>, 2019. # Hasibul Hasan <hasibeng78@gmail.com>, 2019. # Oymate <dhruboadittya96@gmail.com>, 2020. -# Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020. +# Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020, 2021. # Sagen Soren <sagensoren03@gmail.com>, 2020. # Hasibul Hasan <d1hasib@yahoo.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-27 02:25+0000\n" +"PO-Revision-Date: 2021-02-01 20:53+0000\n" "Last-Translator: Mokarrom Hossain <mhb2016.bzs@gmail.com>\n" "Language-Team: Bengali <https://hosted.weblate.org/projects/godot-engine/" "godot/bn/>\n" @@ -24,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -268,7 +268,6 @@ msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" msgstr "লà§à¦ª Wrap মোড (লà§à¦ª দিয়ে শà§à¦°à§ দিয়ে ইনà§à¦Ÿà¦¾à¦°à¦ªà§‹à¦²à§‡à¦Ÿ শেষ)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Remove this track." msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ টà§à¦°à§à¦¯à¦¾à¦•/পথ অপসারণ করà§à¦¨à¥¤" @@ -451,17 +450,15 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• যোগ ঠ#: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "টà§à¦°à§à¦¯à¦¾à¦• পাথটি অবৈধ, সà§à¦¤à¦°à¦¾à¦‚ কোনও পদà§à¦§à¦¤à¦¿ key যà§à¦•à§à¦¤ করতে পারে না।" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Method Track Key" -msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡ (Anim) টà§à¦°à§à¦¯à¦¾à¦•/পথ à¦à¦¬à¦‚ চাবি যোগ করà§à¦¨" +msgstr "Method Track Key যà§à¦•à§à¦¤ করà§à¦¨" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Method not found in object: " -msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-পà§à¦°à¦¾à¦ªà¦• (VariableGet) পাওয়া যায়নি: " +msgstr "Object ঠMethod পাওয়া যায় নি: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -472,7 +469,6 @@ msgid "Clipboard is empty" msgstr "কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Paste Tracks" msgstr "মানসমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨" @@ -484,6 +480,7 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° (Anim) চাবিসমূহেà msgid "" "This option does not work for Bezier editing, as it's only a single track." msgstr "" +"à¦à¦‡ বিকলà§à¦ªà¦Ÿà¦¿ বেজিয়ার সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦° জনà§à¦¯ কাজ করে না, কারণ à¦à¦Ÿà¦¿ কেবলমাতà§à¦° Single টà§à¦°à§à¦¯à¦¾à¦•।" #: editor/animation_track_editor.cpp msgid "" @@ -497,16 +494,23 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"à¦à¦‡ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦Ÿà¦¿ আমদানি করা দৃশà§à¦¯à§‡à¦° সাথে সমà§à¦ªà¦°à§à¦•িত, তাই আমদানি করা টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿à¦¤à§‡ " +"পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করা হবে না।\n" +"\n" +"কাসà§à¦Ÿà¦® টà§à¦°à§à¦¯à¦¾à¦• যà§à¦•à§à¦¤ করার কà§à¦·à¦®à¦¤à¦¾ সকà§à¦·à¦® করতে, দৃশà§à¦¯à§‡à¦° আমদানি সেটিংসে নেà¦à¦¿à¦—েট করà§à¦¨ à¦à¦¬à¦‚ " +"সেট করà§à¦¨\n" +"\"ফাইলগà§à¦²à¦¿\" ঠ\"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨> সঞà§à¦šà¦¯à¦¼à¦¸à§à¦¥à¦¾à¦¨\", \"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨> কাসà§à¦Ÿà¦® টà§à¦°à§à¦¯à¦¾à¦• রাখà§à¦¨\" সকà§à¦·à¦® " +"করà§à¦¨, তারপরে পà§à¦¨à¦°à¦¾à¦¯à¦¼ আমদানি করà§à¦¨à¥¤\n" +"বিকলà§à¦ªà¦à¦¾à¦¬à§‡, à¦à¦•টি আমদানি পà§à¦°à¦¿à¦¸à§‡à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ যা পৃথক ফাইলগà§à¦²à¦¿à¦¤à§‡ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦—à§à¦²à¦¿ " +"আমদানি করে।" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "সতরà§à¦•তা: Imported অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করা হচà§à¦›à§‡" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select an AnimationPlayer node to create and edit animations." -msgstr "" -"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦¸à¦®à§‚হ সমà§à¦ªà¦¾à¦¦à¦¨ করতে দৃশà§à¦¯à§‡à¦° তালিকা থেকে à¦à¦•টি AnimationPlayer নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤" +msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ তৈরি à¦à¦¬à¦‚ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করতে à¦à¦•টি অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নোড নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -569,9 +573,8 @@ msgid "Duplicate Transposed" msgstr "পকà§à¦·à¦¾à¦¨à§à¦¤à¦°à¦¿à¦¤ (Transposed) সমূহ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Selection" -msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨" +msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ Delete করà§à¦¨" #: editor/animation_track_editor.cpp msgid "Go to Next Step" @@ -1487,14 +1490,12 @@ msgstr "" "পারবে না।" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing built-in type name." msgstr "" "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ পূরà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ ধরণের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ " "হতে পারবে না।" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." msgstr "" "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ সারà§à¦¬à¦œà¦¨à§€à¦¨ ধà§à¦°à§à¦¬à¦•ের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ " @@ -1774,14 +1775,12 @@ msgid "Enabled Properties:" msgstr "পà§à¦°à§‹à¦ªà¦¾à¦°à§à¦Ÿà¦¿-সমূহ:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "গঠনবিনà§à¦¯à¦¾à¦¸" +msgstr "গঠনবিনà§à¦¯à¦¾à¦¸ :" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" +msgstr "Enabled কà§à¦²à¦¾à¦¸:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." @@ -7823,6 +7822,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "সেল (Cell)-à¦à¦° আকার:" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "অবজেকà§à¦Ÿ আà¦à¦•া হয়েছে" diff --git a/editor/translations/br.po b/editor/translations/br.po index a20210c2bc..94fec8b3b1 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -7074,6 +7074,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index ed171e7934..c728113731 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -7466,6 +7466,11 @@ msgid "Yaw" msgstr "Guinyada" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Mida: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objectes Dibuixats" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index b37b7d15cd..c3be08c016 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -7320,6 +7320,11 @@ msgid "Yaw" msgstr "Náklon" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Velikost: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekty vykreslené" diff --git a/editor/translations/da.po b/editor/translations/da.po index 1a461ad0f4..2231930b01 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -15,15 +15,15 @@ # Mads K. Bredager <mbredager@gmail.com>, 2019. # Kristoffer Andersen <kjaa@google.com>, 2019. # Joe Osborne <reachjoe.o@gmail.com>, 2020. -# Autowinto <happymansi@hotmail.com>, 2020. +# Autowinto <happymansi@hotmail.com>, 2020, 2021. # Mikkel Mouridsen <mikkelmouridsen@me.com>, 2020, 2021. # snakatk <snaqii@live.dk>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-26 16:32+0000\n" -"Last-Translator: Mikkel Mouridsen <mikkelmouridsen@me.com>\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" +"Last-Translator: snakatk <snaqii@live.dk>\n" "Language-Team: Danish <https://hosted.weblate.org/projects/godot-engine/" "godot/da/>\n" "Language: da\n" @@ -142,7 +142,7 @@ msgstr "Tilføj Bezier-punkt" #: editor/animation_bezier_editor.cpp msgid "Move Bezier Points" -msgstr "Flyt punkt" +msgstr "Flyt Bezier-punkter" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" @@ -198,9 +198,8 @@ msgid "Anim Multi Change Call" msgstr "Anim Skift Call" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Length" -msgstr "Ændre Animation Navn:" +msgstr "Ændre Animationslængde" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -7584,6 +7583,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/de.po b/editor/translations/de.po index d4f7db5298..79b57dac4e 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -7426,6 +7426,11 @@ msgid "Yaw" msgstr "Gieren" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Größe: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Gezeichnete Objekte" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index b9cf1e9087..5c298ea575 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -7052,6 +7052,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index fee8490872..abbfbaedfc 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -7385,6 +7385,11 @@ msgid "Yaw" msgstr "ΠαÏÎκκλιση" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "ΜÎγεθος: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ΖωγÏαφισμÎνα αντικείμενα" diff --git a/editor/translations/eo.po b/editor/translations/eo.po index bd5d35cf43..64b727be90 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -7183,6 +7183,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/es.po b/editor/translations/es.po index 0b354dbd08..c6f5ff06d7 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -7429,6 +7429,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamaño: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Dibujados" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 4a3624c026..4f32171d5f 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -3,7 +3,7 @@ # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. # Diego López <diegodario21@gmail.com>, 2017. -# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018, 2019, 2020. +# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018, 2019, 2020, 2021. # Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018. # Sebastian Silva <sebastian@sugarlabs.org>, 2016. # Jose Luis Bossio <joseluisbossio@gmail.com>, 2018. @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-29 21:52+0000\n" +"PO-Revision-Date: 2021-01-29 19:32+0000\n" "Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" @@ -30,7 +30,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2408,7 +2408,7 @@ msgstr "No hay escena definida para ejecutar." #: editor/editor_node.cpp msgid "Save scene before running..." -msgstr "" +msgstr "Guardar escena antes de ejecutar..." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -5193,14 +5193,13 @@ msgid "Assets ZIP File" msgstr "Archivo ZIP de Assets" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" "Save your scene and try again." msgstr "" -"No se pudo determinar una ruta de guardado para las imagenes de lightmap.\n" -"Guardá tu escena (para imagenes a ser guardadas en el mismo directorio), o " -"elegà una ruta de guardado desde las propiedades de BakedLightmap." +"No se puede determinar una ruta de guardado para las imágenes de los " +"lightmaps.\n" +"Guardá tu escena e inténtalo de nuevo." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5219,26 +5218,31 @@ msgstr "" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed determining lightmap size. Maximum lightmap size too small?" msgstr "" +"Falló al determinar el tamaño del lightmap ¿El tamaño máximo de lightmap es " +"demasiado pequeño?" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Some mesh is invalid. Make sure the UV2 channel values are contained within " "the [0.0,1.0] square region." msgstr "" +"Alguna malla es inválida. Asegurate de que los valores del canal UV2 estén " +"contenidos dentro de la región cuadrada [0,0,1,0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" +"El editor de Godot se compiló sin soporte de ray tracing, los lightmaps no " +"pueden ser bakeados." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "Bake Lightmaps" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "Select lightmap bake file:" -msgstr "Elegir Archivo de Plantilla" +msgstr "Selecciona un archivo de lightmap bakeado:" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6336,9 +6340,8 @@ msgstr "" "Solo se puede setear un punto en un material de proceso ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Convert to CPUParticles2D" -msgstr "Convertir A CPUParticles" +msgstr "Convertir a CPUParticles2D" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -7374,6 +7377,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamaño: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Dibujados" @@ -11624,36 +11632,31 @@ msgstr "Asignar un recurso MeshLibrary a este GridMap para usar sus meshes." #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Begin Bake" -msgstr "" +msgstr "Iniciar Bake" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Preparing data structures" -msgstr "" +msgstr "Preparando estructuras de datos" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Generate buffers" -msgstr "Generar AABB" +msgstr "Generar buffers" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Direct lighting" -msgstr "Direcciones" +msgstr "Iluminación directa" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Indirect lighting" -msgstr "Indentar a la Der" +msgstr "Iluminación indirecta" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Post processing" -msgstr "Post-Procesado" +msgstr "Post procesado" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Plotting lightmaps" -msgstr "Trazando Luces:" +msgstr "Trazando lightmatps" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -12173,7 +12176,7 @@ msgstr "Seleccionar dispositivo de la lista" #: platform/android/export/export.cpp msgid "Unable to find the 'apksigner' tool." -msgstr "" +msgstr "No se pudo encontrar la herramienta 'apksigner'." #: platform/android/export/export.cpp msgid "" @@ -12195,18 +12198,13 @@ msgstr "" "exportación." #: platform/android/export/export.cpp -#, fuzzy msgid "A valid Android SDK path is required in Editor Settings." msgstr "" -"Ruta del SDK de Android inválida para la compilación personalizada en " -"Configuración del Editor." +"Se requiere una ruta válida al SDK de Android en la Configuración del Editor." #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid Android SDK path in Editor Settings." -msgstr "" -"Ruta del SDK de Android inválida para la compilación personalizada en " -"Configuración del Editor." +msgstr "Ruta del SDK de Android inválida en la Configuración del Editor." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" @@ -12214,23 +12212,22 @@ msgstr "¡No se encontró el directorio 'platform-tools'!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK platform-tools' adb command." -msgstr "" +msgstr "No se pudo encontrar el comando adb en las Android SDK platform-tools." #: platform/android/export/export.cpp -#, fuzzy msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Ruta del SDK de Android inválida para la compilación personalizada en " +"Por favor, comprueba el directorio del SDK de Android especificado en la " "Configuración del Editor." #: platform/android/export/export.cpp -#, fuzzy msgid "Missing 'build-tools' directory!" -msgstr "¡No se encontró el directorio 'platform-tools'!" +msgstr "¡No se encontró el directorio 'build-tools'!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK build-tools' apksigner command." msgstr "" +"No se pudo encontrar el comando apksigner en las Android SDK build-tools." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12713,27 +12710,23 @@ msgstr "ARVROrigin requiere un nodo hijo ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" -msgstr "" +msgstr "Encontrar mallas y luces" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing geometry (%d/%d)" -msgstr "Parseando GeometrÃa..." +msgstr "Preparando geometrÃa (%d/%d)" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing environment" -msgstr "Ver Entorno" +msgstr "Preparando entorno" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generating capture" -msgstr "Generando Lightmaps" +msgstr "Generando capturas" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Saving lightmaps" -msgstr "Generando Lightmaps" +msgstr "Guardando lightmaps" #: scene/3d/baked_lightmap.cpp msgid "Done" @@ -13142,6 +13135,8 @@ msgid "" "The sampler port is connected but not used. Consider changing the source to " "'SamplerPort'." msgstr "" +"El puerto de muestreo está conectado, pero no se utiliza. Considerá la " +"posibilidad de cambiar la fuente a \"SamplerPort\"." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/et.po b/editor/translations/et.po index a6576ad312..d0eb9f05e4 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2021-01-22 10:21+0000\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" "Last-Translator: Kritzmensch <streef.gtx@gmail.com>\n" "Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/" "godot/et/>\n" @@ -4953,7 +4953,7 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Import..." -msgstr "" +msgstr "Impordi..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Plugins..." @@ -7106,6 +7106,10 @@ msgid "Yaw" msgstr "Sagitaal" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekte kuvatud" @@ -9579,12 +9583,17 @@ msgid "" "Please edit the project and set the main scene in the Project Settings under " "the \"Application\" category." msgstr "" +"Projekti ei saa käivitada: peastseeni ei ole määratud.\n" +"Redigeerige project.godot faili ja määrake projekti peastseen \"application" +"\" alajaotuses." #: editor/project_manager.cpp msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" +"Projekti ei saa käivitada: varad tuleb importida.\n" +"Redigeerige projekti käivitama algset importimise protsessi." #: editor/project_manager.cpp msgid "Are you sure to run %d projects at once?" @@ -9659,7 +9668,7 @@ msgstr "" #: editor/project_manager.cpp msgid "Can't run project" -msgstr "" +msgstr "Projekti ei saa käivitada" #: editor/project_manager.cpp msgid "" diff --git a/editor/translations/eu.po b/editor/translations/eu.po index cb8cac87ea..f5557a0f3c 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -7074,6 +7074,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index 39983dc201..7445611ef2 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -7379,6 +7379,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 941f970853..765ce4810c 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -7327,6 +7327,11 @@ msgid "Yaw" msgstr "Käännös (yaw)" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Koko: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objekteja piirretty" diff --git a/editor/translations/fil.po b/editor/translations/fil.po index 575e1370b3..ef79d29343 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -7074,6 +7074,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index befd55180d..4493eff913 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -7463,6 +7463,10 @@ msgid "Yaw" msgstr "Lacet (hauteur)" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "Taille" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objets dessinés" diff --git a/editor/translations/ga.po b/editor/translations/ga.po index 6036193c24..206dad7441 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -7068,6 +7068,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/gl.po b/editor/translations/gl.po new file mode 100644 index 0000000000..c3efe67d46 --- /dev/null +++ b/editor/translations/gl.po @@ -0,0 +1,12479 @@ +# LANGUAGE translation of the Godot Engine editor. +# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. +# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). +# This file is distributed under the same license as the Godot source code. +# +# Andy Barcia <andybarcia4@gmail.com>, 2021. +msgid "" +msgstr "" +"Project-Id-Version: Godot Engine editor\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" +"Last-Translator: Andy Barcia <andybarcia4@gmail.com>\n" +"Language-Team: Galician <https://hosted.weblate.org/projects/godot-engine/" +"godot/gl/>\n" +"Language: gl\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.5-dev\n" + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Invalid type argument to convert(), use TYPE_* constants." +msgstr "Tipo de argumento inválido para convert(), utiliza constantes TYPE_*." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +msgid "Expected a string of length 1 (a character)." +msgstr "Esperábase un string de lonxitude 1 (un carácter)." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/mono/glue/gd_glue.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Not enough bytes for decoding bytes, or invalid format." +msgstr "" +"Non hai insuficientes \"bytes\" para descodificar, ou o formato é inválido." + +#: core/math/expression.cpp +msgid "Invalid input %i (not passed) in expression" +msgstr "Entrada inválida %i (non recibida) na expresión" + +#: core/math/expression.cpp +msgid "self can't be used because instance is null (not passed)" +msgstr "Non se pode usar \"self\" porque a instancia é nula (non recibida)" + +#: core/math/expression.cpp +msgid "Invalid operands to operator %s, %s and %s." +msgstr "Operandos inválidos para o operador %s, %s e %s." + +#: core/math/expression.cpp +msgid "Invalid index of type %s for base type %s" +msgstr "Ãndice de tipo %s inválido para tipo base %s" + +#: core/math/expression.cpp +msgid "Invalid named index '%s' for base type %s" +msgstr "O Ãndice do nome '%s' non é válido para o tipo de base %s" + +#: core/math/expression.cpp +msgid "Invalid arguments to construct '%s'" +msgstr "Argumentos inválidos para construir '%s'" + +#: core/math/expression.cpp +msgid "On call to '%s':" +msgstr "En chamada a '%s':" + +#: core/ustring.cpp +msgid "B" +msgstr "B" + +#: core/ustring.cpp +msgid "KiB" +msgstr "KiB" + +#: core/ustring.cpp +msgid "MiB" +msgstr "MiB" + +#: core/ustring.cpp +msgid "GiB" +msgstr "GiB" + +#: core/ustring.cpp +msgid "TiB" +msgstr "TiB" + +#: core/ustring.cpp +msgid "PiB" +msgstr "PiB" + +#: core/ustring.cpp +msgid "EiB" +msgstr "EiB" + +#: editor/animation_bezier_editor.cpp +msgid "Free" +msgstr "Libre" + +#: editor/animation_bezier_editor.cpp +msgid "Balanced" +msgstr "Balanceado" + +#: editor/animation_bezier_editor.cpp +msgid "Mirror" +msgstr "Espello" + +#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp +msgid "Time:" +msgstr "Tempo:" + +#: editor/animation_bezier_editor.cpp +msgid "Value:" +msgstr "Valor:" + +#: editor/animation_bezier_editor.cpp +msgid "Insert Key Here" +msgstr "Introducir Clave AquÃ" + +#: editor/animation_bezier_editor.cpp +msgid "Duplicate Selected Key(s)" +msgstr "Duplicar Clave(s) Seleccionadas(s)" + +#: editor/animation_bezier_editor.cpp +msgid "Delete Selected Key(s)" +msgstr "Eliminar Clave(s) Seleccionada(s)" + +#: editor/animation_bezier_editor.cpp +msgid "Add Bezier Point" +msgstr "Engadir Punto Bezier" + +#: editor/animation_bezier_editor.cpp +msgid "Move Bezier Points" +msgstr "Mover Punto Bezier" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Duplicate Keys" +msgstr "Duplicar Claves de Animación" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Delete Keys" +msgstr "Eliminar Claves de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Time" +msgstr "Cambiar Tempo do Fotograma Clave" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transition" +msgstr "Cambiar Transición de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transform" +msgstr "Cambiar Transformación da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Value" +msgstr "Cambiar Valor do Fotograma Clave da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Call" +msgstr "Cambiar Chamada da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Time" +msgstr "Cambiar Tempo de Múltiples Fotogramas Claves de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transition" +msgstr "Cambiar Múltiples Transicións da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transform" +msgstr "Cambiar Múltiples Transformacións da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Value" +msgstr "Cambiar Múltiples Valores do Fotograma Clave da Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Call" +msgstr "Cambiar Múltiples Chamadas da Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Length" +msgstr "Cambiar Lonxitude da Animación" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation Loop" +msgstr "Cambiar Ciclo da Animación" + +#: editor/animation_track_editor.cpp +msgid "Property Track" +msgstr "Pista de Propiedades" + +#: editor/animation_track_editor.cpp +msgid "3D Transform Track" +msgstr "Pista de Transformación 3D" + +#: editor/animation_track_editor.cpp +msgid "Call Method Track" +msgstr "Pista de Chamadas de Métodos" + +#: editor/animation_track_editor.cpp +msgid "Bezier Curve Track" +msgstr "Pista de Curva Bezier" + +#: editor/animation_track_editor.cpp +msgid "Audio Playback Track" +msgstr "Pista de Reprodución de Audio" + +#: editor/animation_track_editor.cpp +msgid "Animation Playback Track" +msgstr "Pista de Reprodución de Animación" + +#: editor/animation_track_editor.cpp +msgid "Animation length (frames)" +msgstr "Lonxitude da Animacion (en fotogramas)" + +#: editor/animation_track_editor.cpp +msgid "Animation length (seconds)" +msgstr "Lonxitude da Animación (en segundos)" + +#: editor/animation_track_editor.cpp +msgid "Add Track" +msgstr "Engadir Pista" + +#: editor/animation_track_editor.cpp +msgid "Animation Looping" +msgstr "Animación en Bucle" + +#: editor/animation_track_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Functions:" +msgstr "Funciones:" + +#: editor/animation_track_editor.cpp +msgid "Audio Clips:" +msgstr "Clips de Audio:" + +#: editor/animation_track_editor.cpp +msgid "Anim Clips:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Change Track Path" +msgstr "Cambiar Ruta da Pista" + +#: editor/animation_track_editor.cpp +msgid "Toggle this track on/off." +msgstr "Act./Desact. esta pista." + +#: editor/animation_track_editor.cpp +msgid "Update Mode (How this property is set)" +msgstr "Modo de Actualización (cómo se establece esta propiedade)" + +#: editor/animation_track_editor.cpp +msgid "Interpolation Mode" +msgstr "Modo de Interpolación" + +#: editor/animation_track_editor.cpp +msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" +msgstr "Modo de Bucle Envolvente (interpola o final co comezo do bucle)" + +#: editor/animation_track_editor.cpp +msgid "Remove this track." +msgstr "Eliminar esta pista." + +#: editor/animation_track_editor.cpp +msgid "Time (s): " +msgstr "Tempo (s): " + +#: editor/animation_track_editor.cpp +msgid "Toggle Track Enabled" +msgstr "Act./Desact. Pista" + +#: editor/animation_track_editor.cpp +msgid "Continuous" +msgstr "Continuo" + +#: editor/animation_track_editor.cpp +msgid "Discrete" +msgstr "Discreto" + +#: editor/animation_track_editor.cpp +msgid "Trigger" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Capture" +msgstr "Captura" + +#: editor/animation_track_editor.cpp +msgid "Nearest" +msgstr "Máis Cercano" + +#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp +#: editor/property_editor.cpp +msgid "Linear" +msgstr "Lineal" + +#: editor/animation_track_editor.cpp +msgid "Cubic" +msgstr "Cúbica" + +#: editor/animation_track_editor.cpp +msgid "Clamp Loop Interp" +msgstr "Interpolación de Bucle Recortado" + +#: editor/animation_track_editor.cpp +msgid "Wrap Loop Interp" +msgstr "Interpolación de Bucle Envolvente" + +#: editor/animation_track_editor.cpp +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key" +msgstr "Engadir Chave" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Key(s)" +msgstr "Duplicar Chave(s)" + +#: editor/animation_track_editor.cpp +msgid "Delete Key(s)" +msgstr "Eliminar Chave(s)" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Update Mode" +msgstr "Cambiar Modo de Actualización da Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Interpolation Mode" +msgstr "Cambiar Modo de Interpolación da Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Loop Mode" +msgstr "Cambiar Modo de Bucle da Animación" + +#: editor/animation_track_editor.cpp +msgid "Remove Anim Track" +msgstr "Eliminar Pista de Animación" + +#: editor/animation_track_editor.cpp +msgid "Create NEW track for %s and insert key?" +msgstr "Crear nova pista para %s e engadir chave?" + +#: editor/animation_track_editor.cpp +msgid "Create %d NEW tracks and insert keys?" +msgstr "Crear %d novas pistas e engadir chaves?" + +#: editor/animation_track_editor.cpp editor/create_dialog.cpp +#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/mesh_instance_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Create" +msgstr "Crear" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert" +msgstr "Engadir Animación" + +#: editor/animation_track_editor.cpp +msgid "AnimationPlayer can't animate itself, only other players." +msgstr "Un AnimationPlayer non pode animarse a si mesmo, só a outros players." + +#: editor/animation_track_editor.cpp +msgid "Anim Create & Insert" +msgstr "Crear e Engadir Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Track & Key" +msgstr "Engadir Pista e Chave de Animación" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Key" +msgstr "Engadir Chave de Animación" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Step" +msgstr "Cambiar Paso de Animación" + +#: editor/animation_track_editor.cpp +msgid "Rearrange Tracks" +msgstr "Reordenar Pistas" + +#: editor/animation_track_editor.cpp +msgid "Transform tracks only apply to Spatial-based nodes." +msgstr "As pistas de transformación só aplÃcanse a nodos basados en Spatial." + +#: editor/animation_track_editor.cpp +msgid "" +"Audio tracks can only point to nodes of type:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" +msgstr "" +"As pistas de audio só poden apuntar a nodos de tipo:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" + +#: editor/animation_track_editor.cpp +msgid "Animation tracks can only point to AnimationPlayer nodes." +msgstr "As pistas de animación só poden apuntar a nodos AnimationPlayer." + +#: editor/animation_track_editor.cpp +msgid "An animation player can't animate itself, only other players." +msgstr "" +"Un reproductor de animacións non pode animarse a si mesmo, só a outros " +"reproductores." + +#: editor/animation_track_editor.cpp +msgid "Not possible to add a new track without a root" +msgstr "Non é posible engadir unha nova pista sen unha raÃz" + +#: editor/animation_track_editor.cpp +msgid "Invalid track for Bezier (no suitable sub-properties)" +msgstr "Pista inválida para Bezier (non hai sub-propiedades axeitadas)" + +#: editor/animation_track_editor.cpp +msgid "Add Bezier Track" +msgstr "Engadir Pista Bezier" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a key." +msgstr "A ruta á pista é inválida, polo que non se poden engadir chaves." + +#: editor/animation_track_editor.cpp +msgid "Track is not of type Spatial, can't insert key" +msgstr "A pista non é de tipo Spatial, e non se pode engadir chave" + +#: editor/animation_track_editor.cpp +msgid "Add Transform Track Key" +msgstr "Engadir Chave de Pista de Transformación" + +#: editor/animation_track_editor.cpp +msgid "Add Track Key" +msgstr "Engadir Chave de Pista" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a method key." +msgstr "" +"A ruta á pista é inválida, polo que non se pode engadir unha clave de método." + +#: editor/animation_track_editor.cpp +msgid "Add Method Track Key" +msgstr "Engadir Chave de Pista de Método" + +#: editor/animation_track_editor.cpp +msgid "Method not found in object: " +msgstr "Método non encontrado no obxecto: " + +#: editor/animation_track_editor.cpp +msgid "Anim Move Keys" +msgstr "Mover Claves de Animación" + +#: editor/animation_track_editor.cpp +msgid "Clipboard is empty" +msgstr "O portapapeis está baleiro" + +#: editor/animation_track_editor.cpp +msgid "Paste Tracks" +msgstr "Pegar Pistas" + +#: editor/animation_track_editor.cpp +msgid "Anim Scale Keys" +msgstr "Escalar Chaves de Animación" + +#: editor/animation_track_editor.cpp +msgid "" +"This option does not work for Bezier editing, as it's only a single track." +msgstr "" +"Esta opción non funciona con edición Bezier, xa que é unha única pista." + +#: editor/animation_track_editor.cpp +msgid "" +"This animation belongs to an imported scene, so changes to imported tracks " +"will not be saved.\n" +"\n" +"To enable the ability to add custom tracks, navigate to the scene's import " +"settings and set\n" +"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks" +"\", then re-import.\n" +"Alternatively, use an import preset that imports animations to separate " +"files." +msgstr "" +"Esta animación pertence a unha escena importada, polo que os cambios nas " +"pistas importadas non quedaran gardados.\n" +"\n" +"Para habilitar a capacidade de engadir pistas personalizadas, vai á " +"configuración de importación da escena e establece\n" +"\"Animación > Almacenamento\" a \"Arquivos\", activa \"Animación > Manter " +"Pistas Personalizadas\", e logo reimportaa.\n" +"Tamén poder usar un preset de importación que importa animacións para " +"separar arquivos." + +#: editor/animation_track_editor.cpp +msgid "Warning: Editing imported animation" +msgstr "Advertencia: Estase editando unha animación importada" + +#: editor/animation_track_editor.cpp +msgid "Select an AnimationPlayer node to create and edit animations." +msgstr "Selecciona un nodo AnimationPlayer para crear e editar animacións." + +#: editor/animation_track_editor.cpp +msgid "Only show tracks from nodes selected in tree." +msgstr "Só mostrar pistas de nodos seleccionados na árbore." + +#: editor/animation_track_editor.cpp +msgid "Group tracks by node or display them as plain list." +msgstr "Agrupar pistas por nodo ou mostralas coma unha simple lista." + +#: editor/animation_track_editor.cpp +msgid "Snap:" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Animation step value." +msgstr "Valor de paso de animación." + +#: editor/animation_track_editor.cpp +msgid "Seconds" +msgstr "Segundos" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "FPS" +msgstr "FPS" + +#: editor/animation_track_editor.cpp editor/editor_properties.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit" +msgstr "Editar" + +#: editor/animation_track_editor.cpp +msgid "Animation properties." +msgstr "Propiedades de Animación." + +#: editor/animation_track_editor.cpp +msgid "Copy Tracks" +msgstr "Copiar Pistas" + +#: editor/animation_track_editor.cpp +msgid "Scale Selection" +msgstr "Escalar Selección" + +#: editor/animation_track_editor.cpp +msgid "Scale From Cursor" +msgstr "Escalar desde o Cursor" + +#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp +msgid "Duplicate Selection" +msgstr "Duplicar Selección" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Transposed" +msgstr "Duplicar Transposto" + +#: editor/animation_track_editor.cpp +msgid "Delete Selection" +msgstr "Eliminar Selección" + +#: editor/animation_track_editor.cpp +msgid "Go to Next Step" +msgstr "Ir ao Seguinte Paso" + +#: editor/animation_track_editor.cpp +msgid "Go to Previous Step" +msgstr "Ir ao Anterior Paso" + +#: editor/animation_track_editor.cpp +msgid "Optimize Animation" +msgstr "Optimizar Animación" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation" +msgstr "Limpiar Animación" + +#: editor/animation_track_editor.cpp +msgid "Pick the node that will be animated:" +msgstr "Elixe o nodo que será animado:" + +#: editor/animation_track_editor.cpp +msgid "Use Bezier Curves" +msgstr "Usar Curvas Bezier" + +#: editor/animation_track_editor.cpp +msgid "Anim. Optimizer" +msgstr "Optimizador de Animación" + +#: editor/animation_track_editor.cpp +msgid "Max. Linear Error:" +msgstr "Erro Lineal Máximo:" + +#: editor/animation_track_editor.cpp +msgid "Max. Angular Error:" +msgstr "Erro Angular Máximo:" + +#: editor/animation_track_editor.cpp +msgid "Max Optimizable Angle:" +msgstr "Ãngulo Optimizable Máximo:" + +#: editor/animation_track_editor.cpp +msgid "Optimize" +msgstr "Optimizar" + +#: editor/animation_track_editor.cpp +msgid "Remove invalid keys" +msgstr "Eliminar chaves inválidas" + +#: editor/animation_track_editor.cpp +msgid "Remove unresolved and empty tracks" +msgstr "Eliminar pistas baleiras e sen resolver" + +#: editor/animation_track_editor.cpp +msgid "Clean-up all animations" +msgstr "Limpiar tódolas animacións" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation(s) (NO UNDO!)" +msgstr "Limpiar Animación(s) (NON HAI VOLTA ATRÃS!)" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up" +msgstr "Limpiar" + +#: editor/animation_track_editor.cpp +msgid "Scale Ratio:" +msgstr "Relación de Escalado:" + +#: editor/animation_track_editor.cpp +msgid "Select Tracks to Copy" +msgstr "Selecciona as Pistas a Copiar" + +#: editor/animation_track_editor.cpp editor/editor_log.cpp +#: editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Copy" +msgstr "Copiar" + +#: editor/animation_track_editor.cpp +msgid "Select All/None" +msgstr "Seleccionar Todas/Ningunha" + +#: editor/animation_track_editor_plugins.cpp +msgid "Add Audio Track Clip" +msgstr "Engadir Clip de Pista de Audio" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip Start Offset" +msgstr "" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip End Offset" +msgstr "" + +#: editor/array_property_edit.cpp +msgid "Resize Array" +msgstr "Redimensionar Array" + +#: editor/array_property_edit.cpp +msgid "Change Array Value Type" +msgstr "Cambiar Tipo do Valor do Array" + +#: editor/array_property_edit.cpp +msgid "Change Array Value" +msgstr "Cambiar Valor do Array" + +#: editor/code_editor.cpp +msgid "Go to Line" +msgstr "Ir a Liña" + +#: editor/code_editor.cpp +msgid "Line Number:" +msgstr "Número de Liña:" + +#: editor/code_editor.cpp +msgid "%d replaced." +msgstr "%d substituÃdo." + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d match." +msgstr "%d coincidencia." + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d matches." +msgstr "%d coincidencias." + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Match Case" +msgstr "Coincidir Maiús./Minús." + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Whole Words" +msgstr "Palabras Completas" + +#: editor/code_editor.cpp +msgid "Replace" +msgstr "SubstituÃr" + +#: editor/code_editor.cpp +msgid "Replace All" +msgstr "SubstituÃr Todo" + +#: editor/code_editor.cpp +msgid "Selection Only" +msgstr "Só a Selección" + +#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp +#: editor/plugins/text_editor.cpp +msgid "Standard" +msgstr "Estándar" + +#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp +msgid "Toggle Scripts Panel" +msgstr "Act./Desact. Panel de Scripts" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom In" +msgstr "Aumentar Zoom" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Out" +msgstr "DiminuÃr Zoom" + +#: editor/code_editor.cpp +msgid "Reset Zoom" +msgstr "Reiniciar Zoom" + +#: editor/code_editor.cpp +msgid "Warnings" +msgstr "Avisos" + +#: editor/code_editor.cpp +msgid "Line and column numbers." +msgstr "Números de liña e columna." + +#: editor/connections_dialog.cpp +msgid "Method in target node must be specified." +msgstr "Debe especificarse o método no nodo receptor." + +#: editor/connections_dialog.cpp +msgid "Method name must be a valid identifier." +msgstr "O nome do método debe ser un identificador válido." + +#: editor/connections_dialog.cpp +msgid "" +"Target method not found. Specify a valid method or attach a script to the " +"target node." +msgstr "" +"Non se encontrou o método receptor. Especifique un método válido ou engada " +"un script ao nodo receptor." + +#: editor/connections_dialog.cpp +msgid "Connect to Node:" +msgstr "Conectar ao Nodo:" + +#: editor/connections_dialog.cpp +msgid "Connect to Script:" +msgstr "Conectar ao Script:" + +#: editor/connections_dialog.cpp +msgid "From Signal:" +msgstr "Desde a Sinal:" + +#: editor/connections_dialog.cpp +msgid "Scene does not contain any script." +msgstr "A escena non conteñe ningún script." + +#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp +#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +msgid "Add" +msgstr "Engadir" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/editor_feature_profile.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp +msgid "Remove" +msgstr "Eliminar" + +#: editor/connections_dialog.cpp +msgid "Add Extra Call Argument:" +msgstr "Engadir Argumento Extra á Chamada:" + +#: editor/connections_dialog.cpp +msgid "Extra Call Arguments:" +msgstr "Argumentos Extra da Chamada:" + +#: editor/connections_dialog.cpp +msgid "Receiver Method:" +msgstr "Método Receptor:" + +#: editor/connections_dialog.cpp +msgid "Advanced" +msgstr "Avanzado" + +#: editor/connections_dialog.cpp +msgid "Deferred" +msgstr "Diferido" + +#: editor/connections_dialog.cpp +msgid "" +"Defers the signal, storing it in a queue and only firing it at idle time." +msgstr "" +"Difire a sinal, almacenándoa nunha cola é só executándoa en tempo de " +"inactividade." + +#: editor/connections_dialog.cpp +msgid "Oneshot" +msgstr "Execución Única (Oneshot)" + +#: editor/connections_dialog.cpp +msgid "Disconnects the signal after its first emission." +msgstr "Desconecta a sinal unha vez foi emitida por primeira vez." + +#: editor/connections_dialog.cpp +msgid "Cannot connect signal" +msgstr "No se pode conectar a sinal" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/export_template_manager.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Close" +msgstr "Pechar" + +#: editor/connections_dialog.cpp +msgid "Connect" +msgstr "Conectar" + +#: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "Sinal:" + +#: editor/connections_dialog.cpp +msgid "Connect '%s' to '%s'" +msgstr "Conectar '%s' con '%s'" + +#: editor/connections_dialog.cpp +msgid "Disconnect '%s' from '%s'" +msgstr "Desconectar '%s' de '%s'" + +#: editor/connections_dialog.cpp +msgid "Disconnect all from signal: '%s'" +msgstr "Desconectar todo da sinal: '%s'" + +#: editor/connections_dialog.cpp +msgid "Connect..." +msgstr "Conectar..." + +#: editor/connections_dialog.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Disconnect" +msgstr "Desconectar" + +#: editor/connections_dialog.cpp +msgid "Connect a Signal to a Method" +msgstr "Conectar unha Sinal a un Método" + +#: editor/connections_dialog.cpp +msgid "Edit Connection:" +msgstr "Editar Conexión:" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from the \"%s\" signal?" +msgstr "Está seguro de que quere eliminar tódalas conexións da sinal '%s'?" + +#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp +msgid "Signals" +msgstr "Sinais" + +#: editor/connections_dialog.cpp +msgid "Filter signals" +msgstr "Filtrar sinais" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from this signal?" +msgstr "Está seguro de que quere eliminar tódalas conexións desta sinal?" + +#: editor/connections_dialog.cpp +msgid "Disconnect All" +msgstr "Desconectar Todas" + +#: editor/connections_dialog.cpp +msgid "Edit..." +msgstr "Editar..." + +#: editor/connections_dialog.cpp +msgid "Go To Method" +msgstr "Ir ao Método" + +#: editor/create_dialog.cpp +msgid "Change %s Type" +msgstr "Cambiar o Tipo de %s" + +#: editor/create_dialog.cpp editor/project_settings_editor.cpp +msgid "Change" +msgstr "Cambiar" + +#: editor/create_dialog.cpp +msgid "Create New %s" +msgstr "Crear Novo %s" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp +msgid "Favorites:" +msgstr "Favoritos:" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +msgid "Recent:" +msgstr "Recente:" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search:" +msgstr "Buscar:" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Matches:" +msgstr "Coincidencias:" + +#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp +#: editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Description:" +msgstr "Descrición:" + +#: editor/dependency_editor.cpp +msgid "Search Replacement For:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Dependencies For:" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "" +"Scene '%s' is currently being edited.\n" +"Changes will only take effect when reloaded." +msgstr "" +"A escena '%s' agora mesmo está sendo editada.\n" +"Os cambios so terán efecto cando sexa recargada." + +#: editor/dependency_editor.cpp +msgid "" +"Resource '%s' is in use.\n" +"Changes will only take effect when reloaded." +msgstr "" +"O recurso '%s' agora mesmo está sendo usado.\n" +"Os cambios so terán efecto cando sexa recargado." + +#: editor/dependency_editor.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dependencies" +msgstr "Dependencias" + +#: editor/dependency_editor.cpp +msgid "Resource" +msgstr "Recurso" + +#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp +#: editor/project_manager.cpp editor/project_settings_editor.cpp +msgid "Path" +msgstr "Ruta" + +#: editor/dependency_editor.cpp +msgid "Dependencies:" +msgstr "Dependencias:" + +#: editor/dependency_editor.cpp +msgid "Fix Broken" +msgstr "" + +#: editor/dependency_editor.cpp +msgid "Dependency Editor" +msgstr "Editor de Dependencias" + +#: editor/dependency_editor.cpp +msgid "Search Replacement Resource:" +msgstr "Buscar Recurso de Substitución:" + +#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +#: scene/gui/file_dialog.cpp +msgid "Open" +msgstr "Abrir" + +#: editor/dependency_editor.cpp +msgid "Owners Of:" +msgstr "Dono De:" + +#: editor/dependency_editor.cpp +msgid "" +"Remove selected files from the project? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" +"Eliminar do proxecto os arquivos seleccionados? (non se pode reverter)\n" +"Podes encontrar os arquivos eliminados na papeleira de reciclaxe do sistema " +"para restaurarlos." + +#: editor/dependency_editor.cpp +msgid "" +"The files being removed are required by other resources in order for them to " +"work.\n" +"Remove them anyway? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" +"Os arquivos sendo eliminados están requeridos por outros recursos para poder " +"funcionar.\n" +"Eliminalos de todas formas? (non se pode reverter)\n" +"Podes encontrar os arquivos eliminados na papeleira de reciclaxe do sistema " +"para restaurarlos." + +#: editor/dependency_editor.cpp +msgid "Cannot remove:" +msgstr "Non se pode eliminar:" + +#: editor/dependency_editor.cpp +msgid "Error loading:" +msgstr "Erro cargando:" + +#: editor/dependency_editor.cpp +msgid "Load failed due to missing dependencies:" +msgstr "Fallou a carga debido a dependencias ausentes:" + +#: editor/dependency_editor.cpp editor/editor_node.cpp +msgid "Open Anyway" +msgstr "Abrir de Todos Modos" + +#: editor/dependency_editor.cpp +msgid "Which action should be taken?" +msgstr "Que acción deberÃa de tomarse?" + +#: editor/dependency_editor.cpp +msgid "Fix Dependencies" +msgstr "Corrixir Dependencias" + +#: editor/dependency_editor.cpp +msgid "Errors loading!" +msgstr "Erros na carga!" + +#: editor/dependency_editor.cpp +msgid "Permanently delete %d item(s)? (No undo!)" +msgstr "Eliminar permanentemente %d obxectos? (Non se pode reverter!)" + +#: editor/dependency_editor.cpp +msgid "Show Dependencies" +msgstr "Amosar Dependencias" + +#: editor/dependency_editor.cpp +msgid "Orphan Resource Explorer" +msgstr "Explorador de Recursos Orfos" + +#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp +msgid "Delete" +msgstr "Eliminar" + +#: editor/dependency_editor.cpp +msgid "Owns" +msgstr "É Dono de" + +#: editor/dependency_editor.cpp +msgid "Resources Without Explicit Ownership:" +msgstr "" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Key" +msgstr "Cambiar Chave do Dicionario" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Value" +msgstr "Cambiar Valor do Dicionario" + +#: editor/editor_about.cpp +msgid "Thanks from the Godot community!" +msgstr "Moitas grazas de parte da comunidade de Godot!" + +#: editor/editor_about.cpp +msgid "Godot Engine contributors" +msgstr "Colaboradores de Godot Engine" + +#: editor/editor_about.cpp +msgid "Project Founders" +msgstr "Fundadores do Proxecto" + +#: editor/editor_about.cpp +msgid "Lead Developer" +msgstr "Desenvolvedor LÃder" + +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. +#: editor/editor_about.cpp +msgid "Project Manager " +msgstr "Xestor do Proxecto " + +#: editor/editor_about.cpp +msgid "Developers" +msgstr "Desenvolvedores" + +#: editor/editor_about.cpp +msgid "Authors" +msgstr "Autores" + +#: editor/editor_about.cpp +msgid "Platinum Sponsors" +msgstr "Patrocinadores Platino" + +#: editor/editor_about.cpp +msgid "Gold Sponsors" +msgstr "Patrocinadores Ouro" + +#: editor/editor_about.cpp +msgid "Silver Sponsors" +msgstr "Patrocinadores Prata" + +#: editor/editor_about.cpp +msgid "Bronze Sponsors" +msgstr "Patrocinadores Bronce" + +#: editor/editor_about.cpp +msgid "Mini Sponsors" +msgstr "Patrocinadores Mini" + +#: editor/editor_about.cpp +msgid "Gold Donors" +msgstr "Doadores Ouro" + +#: editor/editor_about.cpp +msgid "Silver Donors" +msgstr "Doadores Prata" + +#: editor/editor_about.cpp +msgid "Bronze Donors" +msgstr "Doadores Bronce" + +#: editor/editor_about.cpp +msgid "Donors" +msgstr "Doadores" + +#: editor/editor_about.cpp +msgid "License" +msgstr "Licenza" + +#: editor/editor_about.cpp +msgid "Third-party Licenses" +msgstr "Licenzas de Terceiros" + +#: editor/editor_about.cpp +msgid "" +"Godot Engine relies on a number of third-party free and open source " +"libraries, all compatible with the terms of its MIT license. The following " +"is an exhaustive list of all such third-party components with their " +"respective copyright statements and license terms." +msgstr "" +"Godot Engine depende dun número de bibliotecas de terceiros, gratis e open " +"source; todas compatibles cos termos da licenza MIT. A seguinte e unha lista " +"exhaustiva dos devanditos compoñentes de terceiros, coas suas respectivas " +"declaracións de copyright e termos de licenza." + +#: editor/editor_about.cpp +msgid "All Components" +msgstr "Todos os Compoñentes" + +#: editor/editor_about.cpp +msgid "Components" +msgstr "Compoñentes" + +#: editor/editor_about.cpp +msgid "Licenses" +msgstr "Licenzas" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Error opening package file, not in ZIP format." +msgstr "Erro ao abrir o arquivo comprimido, non está en formato ZIP." + +#: editor/editor_asset_installer.cpp +msgid "%s (Already Exists)" +msgstr "%s (Xa Existe)" + +#: editor/editor_asset_installer.cpp +msgid "Uncompressing Assets" +msgstr "Descomprimindo Assets" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "The following files failed extraction from package:" +msgstr "Os seguintes arquivos non se poideron extraer do paquete:" + +#: editor/editor_asset_installer.cpp +msgid "And %s more files." +msgstr "E %s arquivos máis." + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Package installed successfully!" +msgstr "Paquete instalado correctamente!" + +#: editor/editor_asset_installer.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Success!" +msgstr "Éxito!" + +#: editor/editor_asset_installer.cpp +msgid "Package Contents:" +msgstr "Contenido do Paquete:" + +#: editor/editor_asset_installer.cpp editor/editor_node.cpp +msgid "Install" +msgstr "Instalar" + +#: editor/editor_asset_installer.cpp +msgid "Package Installer" +msgstr "Instalador de Paquetes" + +#: editor/editor_audio_buses.cpp +msgid "Speakers" +msgstr "Altofalantes" + +#: editor/editor_audio_buses.cpp +msgid "Add Effect" +msgstr "Engadir Efecto" + +#: editor/editor_audio_buses.cpp +msgid "Rename Audio Bus" +msgstr "Renomear Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Change Audio Bus Volume" +msgstr "Cambiar Volume do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Solo" +msgstr "Act./Desact. Solo do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Mute" +msgstr "Act./Desact. Silencio do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Bypass Effects" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Select Audio Bus Send" +msgstr "Seleccionar EnvÃo do Bus de Audio" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus Effect" +msgstr "Engadir Efecto ao Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Move Bus Effect" +msgstr "Mover Efecto do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Delete Bus Effect" +msgstr "Eliminar Efecto do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Drag & drop to rearrange." +msgstr "Arrastrar e soltar para reordenar." + +#: editor/editor_audio_buses.cpp +msgid "Solo" +msgstr "Solo" + +#: editor/editor_audio_buses.cpp +msgid "Mute" +msgstr "Silenciar" + +#: editor/editor_audio_buses.cpp +msgid "Bypass" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Bus options" +msgstr "Opcións de Bus" + +#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Duplicate" +msgstr "Duplicar" + +#: editor/editor_audio_buses.cpp +msgid "Reset Volume" +msgstr "Restablecer Volume" + +#: editor/editor_audio_buses.cpp +msgid "Delete Effect" +msgstr "Eliminar Efecto" + +#: editor/editor_audio_buses.cpp +msgid "Audio" +msgstr "Son" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus" +msgstr "Engadir Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Master bus can't be deleted!" +msgstr "Non se pode eliminar o Bus mestre!" + +#: editor/editor_audio_buses.cpp +msgid "Delete Audio Bus" +msgstr "Eliminar Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Duplicate Audio Bus" +msgstr "Duplicar Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Reset Bus Volume" +msgstr "Restablecer Volume do Bus" + +#: editor/editor_audio_buses.cpp +msgid "Move Audio Bus" +msgstr "Mover Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "Save Audio Bus Layout As..." +msgstr "Gardar Disposición do Bus de Son Como..." + +#: editor/editor_audio_buses.cpp +msgid "Location for New Layout..." +msgstr "Localización para a Nova Disposición..." + +#: editor/editor_audio_buses.cpp +msgid "Open Audio Bus Layout" +msgstr "Abrir Disposición do Bus de Son" + +#: editor/editor_audio_buses.cpp +msgid "There is no '%s' file." +msgstr "Non hai ningún arquivo '%s'." + +#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp +msgid "Layout" +msgstr "Disposición" + +#: editor/editor_audio_buses.cpp +msgid "Invalid file, not an audio bus layout." +msgstr "Arquivo invalido; non é unha disposición dun Bus de son." + +#: editor/editor_audio_buses.cpp +msgid "Error saving file: %s" +msgstr "Erro gardando o arquivo: %s" + +#: editor/editor_audio_buses.cpp +msgid "Add Bus" +msgstr "Engadir Bus" + +#: editor/editor_audio_buses.cpp +msgid "Add a new Audio Bus to this layout." +msgstr "Engadir un novo Bus de Son a esta disposición." + +#: editor/editor_audio_buses.cpp editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Load" +msgstr "Cargar" + +#: editor/editor_audio_buses.cpp +msgid "Load an existing Bus Layout." +msgstr "Cargar unha disposición de Bus xa existente." + +#: editor/editor_audio_buses.cpp +msgid "Save As" +msgstr "Gardar Como" + +#: editor/editor_audio_buses.cpp +msgid "Save this Bus Layout to a file." +msgstr "Gardar esta disposición de Bus a un arquivo." + +#: editor/editor_audio_buses.cpp editor/import_dock.cpp +msgid "Load Default" +msgstr "Cargar Valores por Defecto" + +#: editor/editor_audio_buses.cpp +msgid "Load the default Bus Layout." +msgstr "Cargar a disposición de Bus por defecto." + +#: editor/editor_audio_buses.cpp +msgid "Create a new Bus Layout." +msgstr "Crear unha nova Disposición de Bus." + +#: editor/editor_autoload_settings.cpp +msgid "Invalid name." +msgstr "Nome inválido." + +#: editor/editor_autoload_settings.cpp +msgid "Valid characters:" +msgstr "Caracteres válidos:" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing engine class name." +msgstr "Non debe coincidir co nome dunha clase xa existente no engine." + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing built-in type name." +msgstr "Non debe coincidir co nome dun tipo xa existente no engine." + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing global constant name." +msgstr "Non debe coincidir co nome dunha constante global xa existente." + +#: editor/editor_autoload_settings.cpp +msgid "Keyword cannot be used as an autoload name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Autoload '%s' already exists!" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Rename Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Toggle AutoLoad Globals" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Move Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Remove Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp +msgid "Enable" +msgstr "Activar" + +#: editor/editor_autoload_settings.cpp +msgid "Rearrange Autoloads" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Can't add autoload:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Add AutoLoad" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp +msgid "Path:" +msgstr "Ruta:" + +#: editor/editor_autoload_settings.cpp +msgid "Node Name:" +msgstr "Nome do Nodo:" + +#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp +#: editor/editor_profiler.cpp editor/project_manager.cpp +#: editor/settings_config_dialog.cpp +msgid "Name" +msgstr "Nome" + +#: editor/editor_autoload_settings.cpp +msgid "Singleton" +msgstr "" + +#: editor/editor_data.cpp editor/inspector_dock.cpp +msgid "Paste Params" +msgstr "Pegar Parámetros" + +#: editor/editor_data.cpp +msgid "Updating Scene" +msgstr "Actualizando Escena" + +#: editor/editor_data.cpp +msgid "Storing local changes..." +msgstr "Gardando cambios locales..." + +#: editor/editor_data.cpp +msgid "Updating scene..." +msgstr "Actualizando escena..." + +#: editor/editor_data.cpp editor/editor_properties.cpp +msgid "[empty]" +msgstr "[baleiro]" + +#: editor/editor_data.cpp +msgid "[unsaved]" +msgstr "[non gardado]" + +#: editor/editor_dir_dialog.cpp +msgid "Please select a base directory first." +msgstr "Por favor, seleccione primeiro un directorio base." + +#: editor/editor_dir_dialog.cpp +msgid "Choose a Directory" +msgstr "Elixir un Directorio" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +#: scene/gui/file_dialog.cpp +msgid "Create Folder" +msgstr "Crear Cartafol" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp +#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp +msgid "Name:" +msgstr "Nome:" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp +msgid "Could not create folder." +msgstr "Non se puido crear cartafol." + +#: editor/editor_dir_dialog.cpp +msgid "Choose" +msgstr "Elixir" + +#: editor/editor_export.cpp +msgid "Storing File:" +msgstr "" + +#: editor/editor_export.cpp +msgid "No export template found at the expected path:" +msgstr "Non se encontrou ningún modelo de exportación na ruta esperada:" + +#: editor/editor_export.cpp +msgid "Packing" +msgstr "Empaquetando" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " +"Etc' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'ETC' para GLES2. Active " +"'Importar Etc' na 'Configuración do Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' texture compression for GLES3. Enable " +"'Import Etc 2' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'ETC2' para GLES3. Active " +"'Importar Etc 2' na 'Configuración do Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" +"A plataforma actual require unha compresión de texturas 'ETC' para o " +"controlador de respaldo a GLES2.\n" +"Active 'Importar Etc' na 'Configuración do Proxecto' ou desactive " +"'Controlador de Respaldo Activado'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for GLES2. Enable " +"'Import Pvrtc' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'PVRTC' para GLES2. " +"Active 'Importar Pvrtc' na 'Configuración do Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " +"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." +msgstr "" +"A plataforma actual require compresión de texturas 'ETC2' ou 'PVRTC' para " +"GLES3. Active 'Importar Etc 2' ou 'Importar Pvrtc' na 'Configuración do " +"Proxecto'." + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" +"A plataforma actual require unha compresión de texturas 'PVRTC' para o " +"controlador de respaldo a GLES2.\n" +"Active 'Importar Pvrtc' na 'Configuración do Proxecto' ou desactive " +"'Controlador de Respaldo Activado'." + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom debug template not found." +msgstr "Non se encontrou un modelo de depuración personalizado." + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom release template not found." +msgstr "" + +#: editor/editor_export.cpp platform/javascript/export/export.cpp +msgid "Template file not found:" +msgstr "Non se encontrou o arquivo do modelo:" + +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "Na exportación de 32 bits o PCK integrado non pode ser maior de 4 GiB." + +#: editor/editor_feature_profile.cpp +msgid "3D Editor" +msgstr "Editor 3D" + +#: editor/editor_feature_profile.cpp +msgid "Script Editor" +msgstr "Editor de Scripts" + +#: editor/editor_feature_profile.cpp +msgid "Asset Library" +msgstr "Biblioteca de Assets" + +#: editor/editor_feature_profile.cpp +msgid "Scene Tree Editing" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Node Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "FileSystem Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Import Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Erase profile '%s'? (no undo)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Profile must be a valid filename and must not contain '.'" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Profile with this name already exists." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled, Properties Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Properties Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Class Options:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enable Contextual Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Properties:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Features:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Classes:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "File '%s' format is invalid, import aborted." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "" +"Profile '%s' already exists. Remove it first before importing, import " +"aborted." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Error saving profile to path: '%s'." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Unset" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Current Profile:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Make Current" +msgstr "" + +#: editor/editor_feature_profile.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "New" +msgstr "" + +#: editor/editor_feature_profile.cpp editor/editor_node.cpp +#: editor/project_manager.cpp +msgid "Import" +msgstr "" + +#: editor/editor_feature_profile.cpp editor/project_export.cpp +msgid "Export" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Available Profiles:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Class Options" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "New profile name:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Erase Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Godot Feature Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Import Profile(s)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Export Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Manage Editor Feature Profiles" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select Current Folder" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File Exists, Overwrite?" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select This Folder" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Copy Path" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Open in File Manager" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +msgid "Show in File Manager" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "New Folder..." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/find_in_files.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Refresh" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Recognized" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Files (*)" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open File(s)" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a Directory" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File or Directory" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/editor_properties.cpp editor/inspector_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp +msgid "Save" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Save a File" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Back" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Forward" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Up" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Hidden Files" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Favorite" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Mode" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Focus Path" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Up" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Down" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go to previous folder." +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go to next folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Go to parent folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Refresh files." +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "(Un)favorite current folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Toggle the visibility of hidden files." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a grid of thumbnails." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a list." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Directories & Files:" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp +#: editor/plugins/style_box_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Preview:" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File:" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "ScanSources" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "" +"There are multiple importers for different types pointing to file %s, import " +"aborted" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "(Re)Importing Assets" +msgstr "" + +#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp +msgid "Top" +msgstr "" + +#: editor/editor_help.cpp +msgid "Class:" +msgstr "" + +#: editor/editor_help.cpp editor/scene_tree_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Inherits:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Inherited by:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Description" +msgstr "" + +#: editor/editor_help.cpp +msgid "Online Tutorials" +msgstr "" + +#: editor/editor_help.cpp +msgid "Properties" +msgstr "" + +#: editor/editor_help.cpp +msgid "override:" +msgstr "" + +#: editor/editor_help.cpp +msgid "default:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Methods" +msgstr "" + +#: editor/editor_help.cpp +msgid "Theme Properties" +msgstr "" + +#: editor/editor_help.cpp +msgid "Enumerations" +msgstr "" + +#: editor/editor_help.cpp +msgid "Constants" +msgstr "" + +#: editor/editor_help.cpp +msgid "Property Descriptions" +msgstr "" + +#: editor/editor_help.cpp +msgid "(value)" +msgstr "" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this property. Please help us by " +"[color=$color][url=$url]contributing one[/url][/color]!" +msgstr "" + +#: editor/editor_help.cpp +msgid "Method Descriptions" +msgstr "" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this method. Please help us by [color=" +"$color][url=$url]contributing one[/url][/color]!" +msgstr "" + +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Help" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Case Sensitive" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Show Hierarchy" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Display All" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Classes Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Methods Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Signals Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Constants Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Properties Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Theme Properties Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Member Type" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Class" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Method" +msgstr "" + +#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp +msgid "Signal" +msgstr "" + +#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp +msgid "Constant" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Property" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Theme Property" +msgstr "" + +#: editor/editor_inspector.cpp editor/project_settings_editor.cpp +msgid "Property:" +msgstr "" + +#: editor/editor_inspector.cpp +msgid "Set" +msgstr "" + +#: editor/editor_inspector.cpp +msgid "Set Multiple:" +msgstr "" + +#: editor/editor_log.cpp +msgid "Output:" +msgstr "" + +#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Copy Selection" +msgstr "" + +#: editor/editor_log.cpp editor/editor_network_profiler.cpp +#: editor/editor_profiler.cpp editor/editor_properties.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/property_editor.cpp editor/scene_tree_dock.cpp +#: editor/script_editor_debugger.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Clear" +msgstr "" + +#: editor/editor_log.cpp +msgid "Clear Output" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +#: editor/editor_profiler.cpp +msgid "Stop" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp +#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp +msgid "Start" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "%s/s" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Down" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Up" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +msgid "Node" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RPC" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RSET" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RPC" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RSET" +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "New Window" +msgstr "" + +#: editor/editor_node.cpp +msgid "Imported resources can't be saved." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: scene/gui/dialogs.cpp +msgid "OK" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Error saving resource!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource can't be saved because it does not belong to the edited scene. " +"Make it unique first." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Save Resource As..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't open file for writing:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Requested file format unknown:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while saving." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Can't open '%s'. The file could have been moved or deleted." +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while parsing '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unexpected end of file '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Missing '%s' or its dependencies." +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while loading '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Saving Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Analyzing" +msgstr "" + +#: editor/editor_node.cpp +msgid "Creating Thumbnail" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a tree root." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This scene can't be saved because there is a cyclic instancing inclusion.\n" +"Please resolve it and then attempt to save again." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " +"be satisfied." +msgstr "" + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "Can't overwrite scene that is still open!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load MeshLibrary for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving MeshLibrary!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load TileSet for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving TileSet!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"An error occurred while trying to save the editor layout.\n" +"Make sure the editor's user data path is writable." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Default editor layout overridden.\n" +"To restore the Default layout to its base settings, use the Delete Layout " +"option and delete the Default layout." +msgstr "" + +#: editor/editor_node.cpp +msgid "Layout name not found!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Restored the Default layout to its base settings." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was imported, so it's not editable.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was instanced or inherited.\n" +"Changes to it won't be kept when saving the current scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource was imported, so it's not editable. Change its settings in the " +"import panel and then re-import." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This scene was imported, so changes to it won't be kept.\n" +"Instancing it or inheriting will allow making changes to it.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This is a remote object, so changes to it won't be kept.\n" +"Please read the documentation relevant to debugging to better understand " +"this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "There is no defined scene to run." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Could not start subprocess!" +msgstr "" + +#: editor/editor_node.cpp editor/filesystem_dock.cpp +msgid "Open Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Base Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open Script..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save & Close" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes to '%s' before closing?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Saved %s modified resource(s)." +msgstr "" + +#: editor/editor_node.cpp +msgid "A root node is required to save the scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Scene As..." +msgstr "" + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "This operation can't be done without a scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Mesh Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a root node." +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Tile Set" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a selected node." +msgstr "" + +#: editor/editor_node.cpp +msgid "Current scene not saved. Open anyway?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't reload a scene that was never saved." +msgstr "" + +#: editor/editor_node.cpp +msgid "Reload Saved Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The current scene has unsaved changes.\n" +"Reload the saved scene anyway? This action cannot be undone." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Run Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quit" +msgstr "" + +#: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp +msgid "Exit the editor?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Manager?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save & Quit" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes to the following scene(s) before quitting?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes the following scene(s) before opening Project Manager?" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This option is deprecated. Situations where refresh must be forced are now " +"considered a bug. Please report." +msgstr "" + +#: editor/editor_node.cpp +msgid "Pick a Main Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Reopen Closed Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to enable addon plugin at: '%s' parsing of config failed." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' There seems to be an error in " +"the code, please check the syntax." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' Base type is not EditorPlugin." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s' Script is not in tool mode." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Scene '%s' was automatically imported, so it can't be modified.\n" +"To make changes to it, a new inherited scene can be created." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Error loading scene, it must be inside the project path. Use 'Import' to " +"open the scene, then save it inside the project path." +msgstr "" + +#: editor/editor_node.cpp +msgid "Scene '%s' has broken dependencies:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Clear Recent Scenes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"No main scene has ever been defined, select one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' does not exist, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' is not a scene file, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Layout" +msgstr "" + +#: editor/editor_node.cpp +msgid "Delete Layout" +msgstr "" + +#: editor/editor_node.cpp editor/import_dock.cpp +#: editor/script_create_dialog.cpp +msgid "Default" +msgstr "" + +#: editor/editor_node.cpp editor/editor_properties.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp +msgid "Show in FileSystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play This Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Undo Close Tab" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Close Other Tabs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Tabs to the Right" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close All Tabs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Switch Scene Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files or folders" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more folders" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files" +msgstr "" + +#: editor/editor_node.cpp +msgid "Dock Position" +msgstr "" + +#: editor/editor_node.cpp +msgid "Distraction Free Mode" +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle distraction-free mode." +msgstr "" + +#: editor/editor_node.cpp +msgid "Add a new scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Go to previously opened scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Copy Text" +msgstr "" + +#: editor/editor_node.cpp +msgid "Next tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Previous tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Filter Files..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Operations with scene files." +msgstr "" + +#: editor/editor_node.cpp +msgid "New Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "New Inherited Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Scene..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Open Recent" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save All Scenes" +msgstr "" + +#: editor/editor_node.cpp +msgid "Convert To..." +msgstr "" + +#: editor/editor_node.cpp +msgid "MeshLibrary..." +msgstr "" + +#: editor/editor_node.cpp +msgid "TileSet..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Undo" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Redo" +msgstr "" + +#: editor/editor_node.cpp +msgid "Miscellaneous project or scene-wide tools." +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +#: editor/script_create_dialog.cpp +msgid "Project" +msgstr "" + +#: editor/editor_node.cpp +msgid "Project Settings..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Set Up Version Control" +msgstr "" + +#: editor/editor_node.cpp +msgid "Shut Down Version Control" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Install Android Build Template..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Data Folder" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp +msgid "Tools" +msgstr "" + +#: editor/editor_node.cpp +msgid "Orphan Resource Explorer..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quit to Project List" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/project_export.cpp +msgid "Debug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Deploy with Remote Debug" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy will make the executable " +"attempt to connect to this computer's IP so the running project can be " +"debugged.\n" +"This option is intended to be used for remote debugging (typically with a " +"mobile device).\n" +"You don't need to enable it to use the GDScript debugger locally." +msgstr "" + +#: editor/editor_node.cpp +msgid "Small Deploy with Network Filesystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy for Android will only " +"export an executable without the project data.\n" +"The filesystem will be provided from the project by the editor over the " +"network.\n" +"On Android, deploying will use the USB cable for faster performance. This " +"option speeds up testing for projects with large assets." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Collision Shapes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, collision shapes and raycast nodes (for 2D and " +"3D) will be visible in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Navigation" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, navigation meshes and polygons will be visible " +"in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Scene Changes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any changes made to the scene in the editor " +"will be replicated in the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Script Changes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any script that is saved will be reloaded in " +"the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" + +#: editor/editor_node.cpp editor/script_create_dialog.cpp +msgid "Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Editor Settings..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Editor Layout" +msgstr "" + +#: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle Fullscreen" +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Data/Settings Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Data Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Settings Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Editor Features..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Export Templates..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp +msgid "Help" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Online Docs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Q&A" +msgstr "" + +#: editor/editor_node.cpp +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp +msgid "Community" +msgstr "" + +#: editor/editor_node.cpp +msgid "About" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play the project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play" +msgstr "" + +#: editor/editor_node.cpp +msgid "Pause the scene execution for debugging." +msgstr "" + +#: editor/editor_node.cpp +msgid "Pause Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Stop the scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play the edited scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play custom scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play Custom Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Changing the video driver requires restarting the editor." +msgstr "" + +#: editor/editor_node.cpp editor/project_settings_editor.cpp +#: editor/settings_config_dialog.cpp +msgid "Save & Restart" +msgstr "" + +#: editor/editor_node.cpp +msgid "Spins when the editor window redraws." +msgstr "" + +#: editor/editor_node.cpp +msgid "Update Continuously" +msgstr "" + +#: editor/editor_node.cpp +msgid "Update When Changed" +msgstr "" + +#: editor/editor_node.cpp +msgid "Hide Update Spinner" +msgstr "" + +#: editor/editor_node.cpp +msgid "FileSystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "Inspector" +msgstr "" + +#: editor/editor_node.cpp +msgid "Expand Bottom Panel" +msgstr "" + +#: editor/editor_node.cpp +msgid "Output" +msgstr "" + +#: editor/editor_node.cpp +msgid "Don't Save" +msgstr "" + +#: editor/editor_node.cpp +msgid "Android build template is missing, please install relevant templates." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Templates" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This will set up your project for custom Android builds by installing the " +"source template to \"res://android/build\".\n" +"You can then apply modifications and build your own custom APK on export " +"(adding modules, changing the AndroidManifest.xml, etc.).\n" +"Note that in order to make custom builds instead of using pre-built APKs, " +"the \"Use Custom Build\" option should be enabled in the Android export " +"preset." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The Android build template is already installed in this project and it won't " +"be overwritten.\n" +"Remove the \"res://android/build\" directory manually before attempting this " +"operation again." +msgstr "" + +#: editor/editor_node.cpp +msgid "Import Templates From ZIP File" +msgstr "" + +#: editor/editor_node.cpp +msgid "Template Package" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "Merge With Existing" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open & Run a Script" +msgstr "" + +#: editor/editor_node.cpp +msgid "New Inherited" +msgstr "" + +#: editor/editor_node.cpp +msgid "Load Errors" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Select" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open 2D Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open 3D Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Script Editor" +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "Open Asset Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open the next Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open the previous Editor" +msgstr "" + +#: editor/editor_node.h +msgid "Warning!" +msgstr "" + +#: editor/editor_path.cpp +msgid "No sub-resources found." +msgstr "" + +#: editor/editor_plugin.cpp +msgid "Creating Mesh Previews" +msgstr "" + +#: editor/editor_plugin.cpp +msgid "Thumbnail..." +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Main Script:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Edit Plugin" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Installed Plugins:" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Update" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Version:" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Author:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Status:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Edit:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Measure:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame Time (sec)" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Average Time (sec)" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame %" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Physics Frame %" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Inclusive" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Self" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame #:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Time" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Calls" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Edit Text:" +msgstr "" + +#: editor/editor_properties.cpp editor/script_create_dialog.cpp +msgid "On" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Layer" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Bit %d, value %d" +msgstr "" + +#: editor/editor_properties.cpp +msgid "[Empty]" +msgstr "" + +#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp +msgid "Assign..." +msgstr "" + +#: editor/editor_properties.cpp +msgid "Invalid RID" +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"The selected resource (%s) does not match any type expected for this " +"property (%s)." +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on resources saved as a file.\n" +"Resource needs to belong to a scene." +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on this resource because it's not set as " +"local to scene.\n" +"Please switch on the 'local to scene' property on it (and all resources " +"containing it up to a node)." +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Pick a Viewport" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New Script" +msgstr "" + +#: editor/editor_properties.cpp editor/scene_tree_dock.cpp +msgid "Extend Script" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New %s" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Make Unique" +msgstr "" + +#: editor/editor_properties.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Paste" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Convert To %s" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Selected node is not a Viewport!" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Size: " +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Page: " +msgstr "" + +#: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "New Key:" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "New Value:" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Add Key/Value Pair" +msgstr "" + +#: editor/editor_run_native.cpp +msgid "" +"No runnable export preset found for this platform.\n" +"Please add a runnable preset in the Export menu or define an existing preset " +"as runnable." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Write your logic in the _run() method." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "There is an edited scene already." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Couldn't instance script:" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Did you forget the 'tool' keyword?" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Couldn't run script:" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Did you forget the '_run' method?" +msgstr "" + +#: editor/editor_spin_slider.cpp +msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Select Node(s) to Import" +msgstr "" + +#: editor/editor_sub_scene.cpp editor/project_manager.cpp +msgid "Browse" +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Scene Path:" +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Import From Node:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Redownload" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Uninstall" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Installed)" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Official export templates aren't available for development builds." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Missing)" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Current)" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Retrieving mirrors, please wait..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove template version '%s'?" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't open export templates zip." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Invalid version.txt format inside templates: %s." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "No version.txt found inside templates." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error creating path for templates:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Extracting Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Importing:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error getting the list of mirrors." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error parsing JSON of mirror list. Please report this issue!" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"No download links found for this version. Direct download is only available " +"for official releases." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Request Failed." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Redirect Loop." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Complete." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Cannot remove temporary file:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"Templates installation failed.\n" +"The problematic templates archives can be found at '%s'." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error requesting URL:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connecting to Mirror..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Disconnected" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Resolving" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't Resolve" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connecting..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't Connect" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connected" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Requesting..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Downloading" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connection Error" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "SSL Handshake Error" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Uncompressing Android Build Sources" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Current Version:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Installed Versions:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Install From File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove Template" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select Template File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Godot Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Export Template Manager" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select mirror from list: (Shift+Click: Open in Browser)" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Status: Import of file failed. Please fix file and reimport manually." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move/rename resources root." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move a folder into itself." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Error moving:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Error duplicating:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Unable to update dependencies:" +msgstr "" + +#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp +msgid "No name provided." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Provided name contains invalid characters." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "A file or folder with this name already exists." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Name contains invalid characters." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"The following files or folders conflict with items in the target location " +"'%s':\n" +"\n" +"%s\n" +"\n" +"Do you wish to overwrite them?" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Renaming file:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Renaming folder:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicating file:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicating folder:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Inherited Scene" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Set As Main Scene" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Open Scenes" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Instance" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Add to Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Remove from Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Edit Dependencies..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "View Owners..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move To..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Scene..." +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "New Script..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Resource..." +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Expand All" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Collapse All" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicate..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move to Trash" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Rename..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Previous Folder/File" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Next Folder/File" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Re-Scan Filesystem" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Toggle Split Mode" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Search files" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"Scanning Files,\n" +"Please Wait..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move" +msgstr "" + +#: editor/filesystem_dock.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/project_manager.cpp editor/rename_dialog.cpp +#: editor/scene_tree_dock.cpp +msgid "Rename" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Overwrite" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Create Scene" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "Create Script" +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +msgid "Find in Files" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Find:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Folder:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Filters:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "" +"Include the files with the following extensions. Add or remove them in " +"ProjectSettings." +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find..." +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp +msgid "Replace..." +msgstr "" + +#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp +msgid "Cancel" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Find: " +msgstr "" + +#: editor/find_in_files.cpp +msgid "Replace: " +msgstr "" + +#: editor/find_in_files.cpp +msgid "Replace all (no undo)" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Searching..." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d match in %d file." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d matches in %d file." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d matches in %d files." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Add to Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Remove from Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Group name already exists." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Invalid group name." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Rename Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Delete Group" +msgstr "" + +#: editor/groups_editor.cpp editor/node_dock.cpp +msgid "Groups" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Nodes Not in Group" +msgstr "" + +#: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp +msgid "Filter nodes" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Nodes in Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Empty groups will be automatically removed." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Group Editor" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Manage Groups" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Single Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes+Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Importing Scene..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating Lightmaps" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating for Mesh: " +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Running Custom Script..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Couldn't load post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Invalid/broken script for post-import (check console):" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Error running post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Did you return a Node-derived object in the `post_import()` method?" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Saving..." +msgstr "" + +#: editor/import_dock.cpp +msgid "%d Files" +msgstr "" + +#: editor/import_dock.cpp +msgid "Set as Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Clear Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Import As:" +msgstr "" + +#: editor/import_dock.cpp +msgid "Preset" +msgstr "" + +#: editor/import_dock.cpp +msgid "Reimport" +msgstr "" + +#: editor/import_dock.cpp +msgid "Save Scenes, Re-Import, and Restart" +msgstr "" + +#: editor/import_dock.cpp +msgid "Changing the type of an imported file requires editor restart." +msgstr "" + +#: editor/import_dock.cpp +msgid "" +"WARNING: Assets exist that use this resource, they may stop loading properly." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Failed to load resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Expand All Properties" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Collapse All Properties" +msgstr "" + +#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Save As..." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Params" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Edit Resource Clipboard" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Resource" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Built-In" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Sub-Resources Unique" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Open in Help" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Create a new resource in memory and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Load an existing resource from disk and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Save the currently edited resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the previous edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the next edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "History of recently edited objects." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Object properties." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Filter properties" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Changes may be lost!" +msgstr "" + +#: editor/multi_node_edit.cpp +msgid "MultiNode Set" +msgstr "" + +#: editor/node_dock.cpp +msgid "Select a single node to edit its signals and groups." +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Edit a Plugin" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Create a Plugin" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Plugin Name:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Subfolder:" +msgstr "" + +#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp +msgid "Language:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Script Name:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Activate now?" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create points." +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "" +"Edit points.\n" +"LMB: Move Point\n" +"RMB: Erase Point" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Erase points." +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Insert Point" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon (Remove Point)" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Remove Polygon And Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Animation" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Load..." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Move Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "This type of node can't be used. Only root nodes are allowed." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Animation Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Remove BlendSpace1D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Move BlendSpace1D Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"AnimationTree is inactive.\n" +"Activate to enable playback, check node warnings if activation fails." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Set the blending position within the space" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Select and move points, create points with RMB." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp +msgid "Enable snap and show grid." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Open Editor" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Open Animation Node" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Triangle already exists." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "BlendSpace2D does not belong to an AnimationTree node." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "No triangles exist, so no blending can take place." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Toggle Auto Triangles" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create triangles by connecting points." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Erase points and triangles." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Generate blend triangles automatically (instead of manually)" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Parameter Changed" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Filters" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Output node can't be added to the blend tree." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Add Node to BlendTree" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Node Moved" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Unable to connect, port may be in use or connection may be invalid." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Connected" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Disconnected" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Set Animation" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Node" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/scene_tree_dock.cpp +msgid "Delete Node(s)" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Toggle Filter On/Off" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Change Filter" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "No animation player set, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Player path set is invalid, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "" +"Animation player has no valid root node path, so unable to retrieve track " +"names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Anim Clips" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Audio Clips" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Functions" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Renamed" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node..." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Edit Filtered Tracks:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Enable Filtering" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Toggle Autoplay" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Anim" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Animation?" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Remove Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Invalid animation name!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation name already exists!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Rename Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Next Changed" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Blend Time" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Load Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Duplicate Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to copy!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation resource on clipboard!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pasted Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Paste Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to edit!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from current pos. (A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from end. (Shift+A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Stop animation playback. (S)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from start. (Shift+D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from current pos. (D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation position (in seconds)." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Scale animation playback globally for the node." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Tools" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Edit Transitions..." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Open in Inspector" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Display list of animations in player." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Autoplay on Load" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Enable Onion Skinning" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Onion Skinning Options" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Directions" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Past" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Future" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Depth" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "1 step" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "2 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "3 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Differences Only" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Force White Modulate" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Include Gizmos (3D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pin AnimationPlayer" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Create New Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +msgid "Error!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Times:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Next (Auto Queue):" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Cross-Animation Blend Times" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Move Node" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition exists!" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Add Transition" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "End" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Immediate" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Sync" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "At End" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Travel" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Start and end nodes are needed for a sub-transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "No playback resource set at path: %s." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Removed" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition Removed" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set Start Node (Autoplay)" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"Select and move nodes.\n" +"RMB to add new nodes.\n" +"Shift+LMB to create connections." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Create new nodes." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Connect nodes." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Remove selected node or transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Toggle autoplay this animation on start, restart or seek to zero." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set the end animation. This is useful for sub-transitions." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition: " +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Play Mode:" +msgstr "" + +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "AnimationTree" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "New name:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Scale:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade In (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade Out (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Auto Restart:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Random Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Start!" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Amount:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 0:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 1:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "X-Fade Time (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Current:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Clear Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Set Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Delete Input" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is valid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is invalid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "OneShot Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend2 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend3 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend4 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeScale Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeSeek Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Transition Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Import Animations..." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Node Filters" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Filters..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Contents:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "View Files" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connection error, please try again." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect to host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response from host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve hostname:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, return code:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Cannot save response to:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Write error." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, too many redirects" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Redirect loop." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, timeout" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Timeout." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Bad download hash, assuming file has been tampered with." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Expected:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Got:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed sha256 hash check" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Asset Download Error:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading (%s / %s)..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Resolving..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Error making request" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Idle" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Install..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Retry" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download Error" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download for this asset is already in progress!" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Least Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (A-Z)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (Z-A)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (A-Z)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (Z-A)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "First" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Previous" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Next" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Last" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "All" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No results for \"%s\"." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Import..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Plugins..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp +msgid "Sort:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/project_settings_editor.cpp +msgid "Category:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Site:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Support" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Official" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Testing" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Loading..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Assets ZIP File" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Can't determine a save path for lightmap images.\n" +"Save your scene and try again." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " +"Light' flag is on." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed creating lightmap images, make sure path is writable." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Bake Lightmaps" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + +#: editor/plugins/camera_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Preview" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Configure Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Primary Line Every:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "steps" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal and Vertical Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate CanvasItem \"%s\" to %d degrees" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Node2D \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Resize Control \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale CanvasItem \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Children of containers have their anchors and margins values overridden by " +"their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Presets for the anchors and margins values of a Control node." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"When active, moving Control nodes changes their anchors instead of their " +"margins." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Top" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Bottom" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Left Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Right Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "VCenter Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "HCenter Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Full Rect" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Keep Ratio" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Anchors only" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors and Margins" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"Overrides game camera with editor viewport camera." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"No game instance running." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Group Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Ungroup Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Paste Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Warning: Children of a container get their position and size determined only " +"by their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Reset" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Select Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Drag: Rotate" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+Drag: Move" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Move Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Show a list of all objects at the position clicked\n" +"(same as Alt+RMB in select mode)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Click to change object's rotation pivot." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Ruler Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle smart snapping." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Smart Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle grid snapping." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Grid Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snapping Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Rotation Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Scale Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap Relative" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Pixel Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Smart Snapping" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Configure Snap..." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Parent" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Sides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Center" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Other Nodes" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock the selected object in place (can't be moved)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock the selected object (can be moved)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Makes sure the object's children are not selectable." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Restores the object's children's ability to be selected." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Skeleton Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Custom Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Always Show Grid" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Helpers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Rulers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Origin" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Viewport" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Group And Lock Icons" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Frame Selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Preview Canvas Scale" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Translation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert keys (based on mask)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Auto insert keys when objects are translated, rotated or scaled (based on " +"mask).\n" +"Keys are only added to existing tracks, no new tracks will be created.\n" +"Keys must be inserted manually for the first time." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Auto Insert Key" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Animation Key and Pose Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key (Existing Tracks)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Copy Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Multiply grid step by 2" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Divide grid step by 2" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Add %s" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Adding %s..." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Cannot instantiate multiple nodes without root." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Create Node" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Error instancing scene from %s" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Default Type" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Drag & drop + Shift : Add node as sibling\n" +"Drag & drop + Alt : Change node type" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Create Polygon3D" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly (Remove Point)" +msgstr "" + +#: editor/plugins/collision_shape_2d_editor_plugin.cpp +msgid "Set Handle" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Load Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Clear Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Particles" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generated Point Count:" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Solid Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Directed Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Capture from Pixel" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Colors" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +msgid "CPUParticles" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Mesh" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Node" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 0" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 1" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease In" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease Out" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Smoothstep" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Curve Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Add Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Left Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Toggle Curve Linear Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Hold Shift to edit tangents individually" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right click to add point" +msgstr "" + +#: editor/plugins/gi_probe_editor_plugin.cpp +msgid "Bake GI Probe" +msgstr "" + +#: editor/plugins/gradient_editor_plugin.cpp +msgid "Gradient Edited" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item %d" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Items" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item List Editor" +msgstr "" + +#: editor/plugins/light_occluder_2d_editor_plugin.cpp +msgid "Create Occluder Polygon" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh is empty!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a Trimesh collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Static Trimesh Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "This doesn't work on scene root!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create a single convex collision shape for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a single convex collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create multiple convex collision shapes for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create any collision shapes." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Shapes" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Navigation Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Contained Mesh is not of type ArrayMesh." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Unwrap failed, mesh may not be manifold?" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "No mesh to debug." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Model has no UV in this layer" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "MeshInstance lacks a Mesh!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh has not surface to create outlines from!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Could not create outline!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a StaticBody and assigns a polygon-based collision shape to it " +"automatically.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a single convex collision shape.\n" +"This is the fastest (but least accurate) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Collision Siblings" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is a performance middle-ground between the two above options." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh..." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a static outline mesh. The outline mesh will have its normals " +"flipped automatically.\n" +"This can be used instead of the SpatialMaterial Grow property when using " +"that property isn't possible." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV1" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV2" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Unwrap UV2 for Lightmap/AO" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Outline Size:" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Channel Debug" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove item %d?" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "" +"Update from existing scene?:\n" +"%s" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Mesh Library" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove Selected Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import from Scene" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Update from Scene" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and no MultiMesh set in node)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and MultiMesh contains no Mesh)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (not a MeshInstance)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (contains no Mesh resource)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No surface source specified." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no geometry)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no faces)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate Surface" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate MultiMesh" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "X-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Y-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Z-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh Up Axis:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Rotation:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Tilt:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Scale:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate" +msgstr "" + +#: editor/plugins/navigation_polygon_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Navigation Polygon" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Convert to CPUParticles" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generating Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generate Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Can only set point into a ParticlesMaterial process material" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generation Time (sec):" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry's faces don't contain any area." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry doesn't contain any faces." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't inherit from Spatial." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain face geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emitter" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Points:" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points+Normal (Directed)" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Volume" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Source: " +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "A processor material of type 'ParticlesMaterial' is required." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generating AABB" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generate Visibility AABB" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Point from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Out-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove In-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point to Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Split Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Point in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move In-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Out-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Select Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Shift+Drag: Select Control Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Click: Add Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Left Click: Split Segment (in curve)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Right Click: Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Select Control Points (Shift+Drag)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point (in empty space)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Close Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp +msgid "Options" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Angles" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Lengths" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Curve Point #" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Point Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve In Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Out Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Path" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Path Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Out-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove In-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Segment (in curve)" +msgstr "" + +#: editor/plugins/physical_bone_plugin.cpp +msgid "Move Joint" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"The skeleton property of the Polygon2D does not point to a Skeleton2D node" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"No texture in this polygon.\n" +"Set a texture to be able to edit UV." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create UV Map" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Polygon 2D has internal vertices, so it can no longer be edited in the " +"viewport." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon & UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Invalid Polygon (need 3 different vertices)" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Add Custom Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Custom Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform UV Map" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint Bone Weights" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Open Polygon 2D UV editor." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygon 2D UV Editor" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Points" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygons" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Points" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Command: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift: Move All" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Command: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Ctrl: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Ctrl: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Rotate Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Scale Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create a custom polygon. Enables custom polygon rendering." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Remove a custom polygon. If none remain, custom polygon rendering is " +"disabled." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Unpaint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Radius:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy Polygon to UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy UV to Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Clear UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Settings" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Snap" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Enable Snap" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Show Grid" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Configure Grid:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones to Polygon" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ERROR: Couldn't load resource!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Add Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Rename Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Resource clipboard is empty!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Paste Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Load Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ResourcePreloader" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "AnimationTree has no path set to an AnimationPlayer" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Path to AnimationPlayer is invalid" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Files" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close and save changes?" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error writing TextFile:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Could not load file at:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving file!" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Saving" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error importing theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Importing" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "New Text File..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open File" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save File As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Can't obtain the script for running." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script failed reloading, check console for errors." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script is not in tool mode, will not be able to run." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"To run this script, it must inherit EditorScript and be set to tool mode." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "%s Class Reference" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Toggle alphabetical sorting of the method list." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Sort" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Up" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Down" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Next script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Previous script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "File" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reopen Closed Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save All" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Soft Reload Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Copy Script Path" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reload Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close All" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close Docs" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +msgid "Run" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Into" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Over" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Break" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +#: editor/script_editor_debugger.cpp +msgid "Continue" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Keep Debugger Open" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Debug with External Editor" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open Godot online documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search the reference documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to previous edited document." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to next edited document." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Discard" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Debugger" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Results" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Scripts" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Connections to method:" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp +msgid "Source" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Target" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "" +"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "[Ignore]" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Only resources from filesystem can be dropped." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't drop nodes because script '%s' is not used in this scene." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Lookup Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Pick Color" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Convert Case" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Uppercase" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Lowercase" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Capitalize" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Syntax Highlighter" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Bookmarks" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Cut" +msgstr "" + +#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Delete Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Left" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Right" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Comment" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold/Unfold Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold All Lines" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Unfold All Lines" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Complete Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Evaluate Selection" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Trim Trailing Whitespace" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Spaces" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Tabs" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Auto Indent" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Find in Files..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Contextual Help" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Bookmarks" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Line..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Toggle Breakpoint" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Breakpoint" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Breakpoint" +msgstr "" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "" +"This shader has been modified on on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "Shader" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "This skeleton has no bones, create some children Bone2D nodes." +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Create Rest Pose from Bones" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Rest Pose to Bones" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Skeleton2D" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Make Rest Pose (From Bones)" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Bones to Rest Pose" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical bones" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Skeleton" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical skeleton" +msgstr "" + +#: editor/plugins/skeleton_ik_editor_plugin.cpp +msgid "Play IK" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Orthogonal" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Aborted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "X-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Y-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Z-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Plane Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scaling: " +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translating: " +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotating %s degrees." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Keying is disabled (no key inserted)." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Animation Key Inserted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pitch" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Yaw" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Objects Drawn" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Material Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Shader Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Surface Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Draw Calls" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Vertices" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Transform with View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Rotation with View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "No parent to instance a child at." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "This operation requires a single selected node." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock View Rotation" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Normal" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Wireframe" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Overdraw" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Unshaded" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Environment" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Information" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View FPS" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Half Resolution" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Audio Listener" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Enable Doppler" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Cinematic Preview" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Not available when using the GLES2 renderer." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Forward" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Backwards" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Up" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Down" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Speed Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Slow Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "XForm Dialog" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Click to toggle between visibility states.\n" +"\n" +"Open eye: Gizmo is visible.\n" +"Closed eye: Gizmo is hidden.\n" +"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Nodes To Floor" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Couldn't find a solid floor to snap the selection to." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Drag: Rotate\n" +"Alt+Drag: Move\n" +"Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Local Space" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Snap" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Switch Perspective/Orthogonal View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Insert Animation Key" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Toggle Freelook" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Object to Floor" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Dialog..." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "1 Viewport" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports (Alt)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports (Alt)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "4 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Grid" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Settings..." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Settings" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate Snap:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Snap (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Snap (%):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Viewport Settings" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective FOV (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Near:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Far:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Change" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale (ratio):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Type" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pre" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Post" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Nameless gizmo" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Mesh2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Polygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Polygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "CollisionPolygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "LightOccluder2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite is empty!" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Can't convert a sprite using animation frames to mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't replace by mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Polygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create collision polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create light occluder." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Simplification: " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Shrink (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Grow (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Update Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Settings:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "No Frames Selected" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add %d Frame(s)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Unable to load images" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "ERROR: Couldn't load frame resource!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Resource clipboard is empty or not a texture!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Paste Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Empty" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation FPS" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "(empty)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animations:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "New Animation" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Speed:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Loop" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animation Frames:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add a Texture from File" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frames from a Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Horizontal:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Vertical:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select/Clear All Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Create Frames from Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "SpriteFrames" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Region Rect" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Margin" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Snap Mode:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +#: scene/resources/visual_shader.cpp +msgid "None" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Pixel Snap" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Grid Snap" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Auto Slice" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Offset:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Step:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Sep.:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "TextureRegion" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp +msgid "Remove All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Edit Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme editing menu." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Editor Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create From Current Editor Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Toggle Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Check Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Named Sep." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Submenu" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Many" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled LineEdit" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 3" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Editable Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subtree" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has,Many,Options" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Data Type:" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Style" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Font" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Color" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme File" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Fix Invalid Tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cut Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Line Draw" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Bucket Fill" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Find Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Transpose" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Disable Autotile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Enable Priority" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Filter tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Give a TileSet resource to this TileMap to use its tiles." +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Command+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Ctrl+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Pick Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Left" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Right" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Horizontally" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Vertically" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Clear Transform" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Add Texture(s) to TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected Texture from TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Single Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Autotile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Atlas" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Next Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the next shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Previous Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the previous shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Copy bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Erase bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new rectangle." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Rectangle" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete Selected Shape" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Keep polygon inside region Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Enable snap and show grid (configurable via the Inspector)." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Display Tile Names (Hold Alt Key)" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Add or select a texture on the left panel to edit the tiles bound to it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected texture? This will remove all tiles which use it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "You haven't selected a texture to remove." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from scene? This will overwrite all current tiles." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from scene?" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Texture" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "%s file(s) were not added because was already on the list." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Drag handles to edit Rect.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete selected Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select current edited sub-tile.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"LMB: Set bit on.\n" +"RMB: Set bit off.\n" +"Shift+LMB: Set wildcard bit.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to use as icon, this will be also used on invalid autotile " +"bindings.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its priority.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its z index.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Icon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Clear Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "This property can't be changed." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "TileSet" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No VCS addons are available." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Error" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No files added to stage" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "VCS Addon is not initialized" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control System" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Initialize" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Staging area" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage Selected" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage All" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Status" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View file diffs before committing them to the latest version" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No file diff is active" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect changes in file diff" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(GLES3 only)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Output" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sampler" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set expression" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Resize VisualShader node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Uniform Name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Input Default Port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node to Visual Shader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Node(s) Moved" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Duplicate Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Input Type Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "UniformRef Name Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vertex" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Fragment" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Light" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Show resulted shader code." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Create Shader Node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Grayscale function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts HSV vector to RGB equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts RGB vector to HSV equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sepia function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Burn operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Darken operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Difference operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Dodge operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "HardLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Lighten operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Overlay operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Screen operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "SoftLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the %s comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Equal (==)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than (>)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than or Equal (>=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided scalars are equal, greater or " +"less." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between NaN and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than (<)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than or Equal (<=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Not Equal (!=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated scalar if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF (or NaN) and a " +"scalar parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for all shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Input parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for light shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "E constant (2.718282). Represents the base of the natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Epsilon constant (0.00001). Smallest possible scalar number." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Phi constant (1.618034). Golden ratio." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/4 constant (0.785398) or 45 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/2 constant (1.570796) or 90 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi constant (3.141593) or 180 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Tau constant (6.283185) or 360 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sqrt2 constant (1.414214). Square root of 2." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the absolute value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Finds the nearest integer that is greater than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Constrains a value to lie between two further values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in radians to degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-e Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer less than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Computes the fractional part of the argument." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse of the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the greater of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the lesser of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the opposite value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the value of the first parameter raised to the power of the second." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in degrees to radians." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest even integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Clamps the value between 0.0 and 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Extracts the sign of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the truncated value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds scalar to scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts scalar from scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the cubic texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Cubic texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup with triplanar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Calculate the outer product of a pair of vectors.\n" +"\n" +"OuterProduct 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'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes transform from four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes transform to four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the determinant of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the inverse of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the transpose of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies transform by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes vector from three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes vector to three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the cross product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the distance between two points." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the dot product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the same direction as a reference vector. " +"The function has three vector parameters : N, the vector to orient, I, the " +"incident vector, and Nref, the reference vector. If the dot product of I and " +"Nref is smaller than zero the return value is N. Otherwise -N is returned." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the length of a vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors using scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the normalize product of vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the direction of reflection ( a : incident " +"vector, b : normal vector )." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the vector that points in the direction of refraction." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( vector(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds vector to vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts vector from vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, with custom amount of input and " +"output ports. This is a direct injection of code into the vertex/fragment/" +"light function, do not use it to write the function declarations inside." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns falloff based on the dot product of surface normal and view " +"direction of camera (pass associated inputs to it)." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, which is placed on top of the " +"resulted shader. You can place various function definitions inside and call " +"it later in the Expressions. You can also declare varyings, uniforms and " +"constants." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "A reference to an existing uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Scalar derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Vector derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "VisualShader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Edit Visual Property" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Mode Changed" +msgstr "" + +#: editor/project_export.cpp +msgid "Runnable" +msgstr "" + +#: editor/project_export.cpp +msgid "Delete preset '%s'?" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"Export templates seem to be missing or invalid." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"This might be due to a configuration issue in the export preset or your " +"export settings." +msgstr "" + +#: editor/project_export.cpp +msgid "Release" +msgstr "" + +#: editor/project_export.cpp +msgid "Exporting All" +msgstr "" + +#: editor/project_export.cpp +msgid "The given export path doesn't exist:" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing/corrupted:" +msgstr "" + +#: editor/project_export.cpp +msgid "Presets" +msgstr "" + +#: editor/project_export.cpp editor/project_settings_editor.cpp +msgid "Add..." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"If checked, the preset will be available for use in one-click deploy.\n" +"Only one preset per platform may be marked as runnable." +msgstr "" + +#: editor/project_export.cpp +msgid "Export Path" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources" +msgstr "" + +#: editor/project_export.cpp +msgid "Export all resources in the project" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected scenes (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected resources (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources to export:" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to export non-resource files/folders\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to exclude files/folders from project\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "Features" +msgstr "" + +#: editor/project_export.cpp +msgid "Custom (comma-separated):" +msgstr "" + +#: editor/project_export.cpp +msgid "Feature List:" +msgstr "" + +#: editor/project_export.cpp +msgid "Script" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Text" +msgstr "" + +#: editor/project_export.cpp +msgid "Compiled" +msgstr "" + +#: editor/project_export.cpp +msgid "Encrypted (Provide Key Below)" +msgstr "" + +#: editor/project_export.cpp +msgid "Invalid Encryption Key (must be 64 characters long)" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Encryption Key (256-bits as hex):" +msgstr "" + +#: editor/project_export.cpp +msgid "Export PCK/Zip" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Project" +msgstr "" + +#: editor/project_export.cpp +msgid "Export mode?" +msgstr "" + +#: editor/project_export.cpp +msgid "Export All" +msgstr "" + +#: editor/project_export.cpp editor/project_manager.cpp +msgid "ZIP File" +msgstr "" + +#: editor/project_export.cpp +msgid "Godot Game Pack" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing:" +msgstr "" + +#: editor/project_export.cpp +msgid "Manage Export Templates" +msgstr "" + +#: editor/project_export.cpp +msgid "Export With Debug" +msgstr "" + +#: editor/project_manager.cpp +msgid "The path specified doesn't exist." +msgstr "" + +#: editor/project_manager.cpp +msgid "Error opening package file (it's not in ZIP format)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose an empty folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose a \"project.godot\" or \".zip\" file." +msgstr "" + +#: editor/project_manager.cpp +msgid "This directory already contains a Godot project." +msgstr "" + +#: editor/project_manager.cpp +msgid "New Game Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Imported Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Invalid Project Name." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't create folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "There is already a folder in this path with the specified name." +msgstr "" + +#: editor/project_manager.cpp +msgid "It would be a good idea to name your project." +msgstr "" + +#: editor/project_manager.cpp +msgid "Invalid project path (changed anything?)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't edit project.godot in project path." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't create project.godot in project path." +msgstr "" + +#: editor/project_manager.cpp +msgid "Rename Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Import Existing Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Import & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Create New Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Create & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Install Project:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Install & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Name:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Path:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Installation Path:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer:" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 3.0" +msgstr "" + +#: editor/project_manager.cpp +msgid "Not supported by your GPU drivers." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Higher visual quality\n" +"All features available\n" +"Incompatible with older hardware\n" +"Not recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 2.0" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Lower visual quality\n" +"Some features not available\n" +"Works on most hardware\n" +"Recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer can be changed later, but scenes may need to be adjusted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Unnamed Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Missing Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Error: Project is missing on the filesystem." +msgstr "" + +#: editor/project_manager.cpp +msgid "Can't open project at '%s'." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to open more than one project?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file does not specify the version of Godot " +"through which it was created.\n" +"\n" +"%s\n" +"\n" +"If you proceed with opening it, it will be converted to Godot's current " +"configuration file format.\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file was generated by an older engine " +"version, and needs to be converted for this version:\n" +"\n" +"%s\n" +"\n" +"Do you want to convert it?\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The project settings were created by a newer engine version, whose settings " +"are not compatible with this version." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Can't run project: no main scene defined.\n" +"Please edit the project and set the main scene in the Project Settings under " +"the \"Application\" category." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Can't run project: Assets need to be imported.\n" +"Please edit the project to trigger the initial import." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to run %d projects at once?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove %d projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove this project from the list?\n" +"The project folder's contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove all missing projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Language changed.\n" +"The interface will update after restarting the editor or project manager." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Are you sure to scan %s folders for existing Godot projects?\n" +"This could take a while." +msgstr "" + +#. TRANSLATORS: This refers to the application where users manage their Godot projects. +#: editor/project_manager.cpp +msgid "Project Manager" +msgstr "" + +#: editor/project_manager.cpp +msgid "Projects" +msgstr "" + +#: editor/project_manager.cpp +msgid "Last Modified" +msgstr "" + +#: editor/project_manager.cpp +msgid "Scan" +msgstr "" + +#: editor/project_manager.cpp +msgid "Select a Folder to Scan" +msgstr "" + +#: editor/project_manager.cpp +msgid "New Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Remove Missing" +msgstr "" + +#: editor/project_manager.cpp +msgid "Templates" +msgstr "" + +#: editor/project_manager.cpp +msgid "Restart Now" +msgstr "" + +#: editor/project_manager.cpp +msgid "Can't run project" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"You currently don't have any projects.\n" +"Would you like to explore official example projects in the Asset Library?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Key " +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joy Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joy Axis" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "An action with the name '%s' already exists." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Rename Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Action deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "All Devices" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device" +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Press a Key..." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Left Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Right Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Middle Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Left Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Right Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "X Button 1" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "X Button 2" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joypad Axis Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Axis" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joypad Button Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Left Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Right Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Middle Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Global Property" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Select a setting item first!" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "No property '%s' exists." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Setting '%s' is internal, and it can't be deleted." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Delete Item" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Error saving settings." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Settings saved OK." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Moved Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Override for Feature" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Translation" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Translation" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Remapped Path" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resource Remap Add Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Resource Remap Language" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap Option" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter Mode" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Project Settings (project.godot)" +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "General" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Override For..." +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "The editor must be restarted for changes to take effect." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Input Map" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Action:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Localization" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Translations" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Translations:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remaps" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resources:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remaps by Locale:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locale" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locales Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Show All Locales" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Show Selected Locales Only" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Filter mode:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locales:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "AutoLoad" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Plugins" +msgstr "" + +#: editor/property_editor.cpp +msgid "Preset..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Zero" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing In-Out" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing Out-In" +msgstr "" + +#: editor/property_editor.cpp +msgid "File..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Dir..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Assign" +msgstr "" + +#: editor/property_editor.cpp +msgid "Select Node" +msgstr "" + +#: editor/property_editor.cpp +msgid "Error loading file: Not a resource!" +msgstr "" + +#: editor/property_editor.cpp +msgid "Pick a Node" +msgstr "" + +#: editor/property_editor.cpp +msgid "Bit %d, val %d." +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Property" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Virtual Method" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Method" +msgstr "" + +#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp +msgid "Batch Rename" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Replace:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Prefix:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Suffix:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Use Regular Expressions" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Advanced Options" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Substitute" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node's parent name, if available" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node type" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Current scene name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Root node name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Sequential integer counter.\n" +"Compare counter options." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Per-level Counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "If set, the counter restarts for each group of child nodes." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Initial value for the counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Step" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Amount by which counter is incremented for each node" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Padding" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Minimum number of digits for the counter.\n" +"Missing digits are padded with leading zeros." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Post-Process" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Keep" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "PascalCase to snake_case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "snake_case to PascalCase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Lowercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Uppercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Reset" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Regular Expression Error:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "At character %s" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent Node" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Reparent Location (Select new Parent):" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Keep Global Transform" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Run Mode:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Current Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene Arguments:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Scene Run Settings" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "No parent to instance the scenes at." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error loading scene from %s" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot instance the scene '%s' because the current scene exists within one " +"of its nodes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Scene(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Replace with Branch Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Child Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on the tree root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Node In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Nodes In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Duplicate Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Node must belong to the edited scene to become root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instantiated scenes can't become root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make node as Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes and any children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete the root node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\" and its children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can not perform with the root node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on instanced scenes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Save New Scene As..." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Disabling \"editable_instance\" will cause all properties of the node to be " +"reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and " +"cause all properties of the node to be reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "New Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Create Root Node:" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "2D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "3D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "User Interface" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Other Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes from a foreign scene!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes the current scene inherits from!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remove Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change type of node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Couldn't save new scene. Likely dependencies (instances) couldn't be " +"satisfied." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error saving scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error duplicating scene to save it." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Sub-Resources" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Editable Children" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Load As Placeholder" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Open Documentation" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot attach a script: there are no languages registered.\n" +"This is probably because this editor was built with all language modules " +"disabled." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add Child Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change Type" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Reparent to New Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Merge From Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Save Branch as Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Copy Node Path" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete (No Confirm)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add/Create a New Node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Instance a scene file as a Node. Creates an inherited scene if no root node " +"exists." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach a new or existing script to the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach the script from the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remote" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance? (No Undo!)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visible" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Unlock Node" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Button Group" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "(Connecting From)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node configuration warning:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s) and %s group(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is in %s group(s).\n" +"Click to show groups dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Open Script:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is locked.\n" +"Click to unlock it." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Children are not selectable.\n" +"Click to make selectable." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visibility" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"AnimationPlayer is pinned.\n" +"Click to unpin." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Invalid node name, the following characters are not allowed:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Rename Node" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Scene Tree (Nodes):" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node Configuration Warning!" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Select a Node" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Path is empty." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Filename is empty." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Path is not local." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid base path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "A directory with the same name exists." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "File does not exist." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid extension." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Wrong extension chosen." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error loading template '%s'" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error - Could not create script in filesystem." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error loading script from %s" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Overrides" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "N/A" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Open Script / Choose Location" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Open Script" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "File exists, it will be reused." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid class name." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid inherited parent name or path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Script path/name is valid." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Allowed: a-z, A-Z, 0-9, _ and ." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Built-in script (into scene file)." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Will create a new script file." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Will load an existing script file." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Script file already exists." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Class Name:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Template:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Built-in Script:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Attach Node Script" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Remote " +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Bytes:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Warning:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Error:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Source:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Trace" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Errors" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Child process connected." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Copy Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Video RAM" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Skip Breakpoints" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Previous Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Next Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Frames" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Profiler" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Network Profiler" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Monitor" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Value" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Monitors" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Pick one or more items from the list to display the graph." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "List of Video Memory Usage by Resource:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Total:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Resource Path" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Type" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Format" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Usage" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Misc" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control Type:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Live Edit Root:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Set From Tree" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export measures as CSV" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Erase Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Restore Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Change Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Editor Settings" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Shortcuts" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Binding" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Light Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change AudioStreamPlayer3D Emission Angle" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera FOV" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera Size" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Notifier AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Particles AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Probe Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Sphere Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Box Shape Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Ray Shape Length" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Height" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Inner Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Outer Radius" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select the dynamic library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select dependencies of the library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Remove current entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Double click to create a new entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform:" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dynamic Library" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Add an architecture entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "GDNativeLibrary" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Enabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Disabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Library" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Libraries: " +msgstr "" + +#: modules/gdnative/register_types.cpp +msgid "GDNative" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Step argument is zero!" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not a script with an instance" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a script" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a resource file" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (missing @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (can't load script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (invalid script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary (invalid subclasses)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Object can't provide a length." +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Delete Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paste Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paint" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Disabled" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Above" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Below" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit X Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Y Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Z Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Clear Rotation" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Paste Selects" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clear Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Settings" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Pick Distance:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Filter meshes" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Give a MeshLibrary resource to this GridMap to use its meshes." +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + +#: modules/mono/csharp_script.cpp +msgid "Class name can't be a reserved keyword" +msgstr "" + +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Bake NavMesh" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Clear the navigation mesh." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Setting up Configuration..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Calculating grid size..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Marking walkable triangles..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Constructing compact heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Eroding walkable area..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Partitioning..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating contours..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating polymesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Converting to native navigation mesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Navigation Mesh Generator Setup:" +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Parsing Geometry..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Done!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"A node yielded without working memory, please read the docs on how to yield " +"properly!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Node yielded, but did not return a function state in the first working " +"memory." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Return value must be assigned to first element of node working memory! Fix " +"your node please." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Node returned an invalid sequence output: " +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Found sequence bit but not the node in the stack, report bug!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Stack overflow with stack depth: " +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Signal Arguments" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Default Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Override an existing built-in function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Variables:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new variable." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Signals:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new signal." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name is not a valid identifier:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name already in use by another func/var/signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete input port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Expression" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Duplicate VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Preload Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node(s) From Tree" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "" +"Can't drop properties because script '%s' is not used in this scene.\n" +"Drop holding 'Shift' to just copy the signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Getter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Setter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Move Node(s)" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Disconnect Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Data" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Sequence" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Script already has function '%s'" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Input Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Resize Comment" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't copy the function node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Clipboard is empty!" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function with a function node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function of nodes from nodes of multiple functions." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select at least one node with sequence port." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Try to only have one sequence input in selection." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Variable:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Tool:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Members:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Nodes..." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function..." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "function_name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select or create a function to edit its graph." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete Selected" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Find Node Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Copy Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Cut Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Refresh Graph" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit Member" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Input type not iterable: " +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid: " +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name." +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Base object is not a Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Path does not lead Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name '%s' in node %s." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid argument of type: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid arguments: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableGet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableSet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Custom node has no _step() method, can't process graph." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "" +"Invalid return value from _step(), must be integer (seq out), or string " +"(error)." +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search VisualScript" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Set %s" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package name is missing." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package segments must be of non-zero length." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' is not allowed in Android application package names." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A digit cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The package must have at least one '.' separator." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Select device from the list" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find the 'apksigner' tool." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Debug keystore not configured in the Editor Settings nor in the preset." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Release keystore incorrectly configured in the export preset." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid Android SDK path in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'platform-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid public key for APK expansion." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid package name:" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" " +"project setting (changed in Godot 3.2.2).\n" +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Use Custom Build\" must be enabled to use the plugins." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR" +"\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android App Bundle requires the *.aab extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "APK Expansion not compatible with Android App Bundle." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android APK requires the *.apk extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Trying to build from a custom built template, but no version info for it " +"exists. Please reinstall from the 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build version mismatch:\n" +" Template installed: %s\n" +" Godot Version: %s\n" +"Please reinstall Android build template from 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Building Android Project (gradle)" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Building of Android project failed, check output for the error.\n" +"Alternatively visit docs.godotengine.org for Android build documentation." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Moving output" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Unable to copy and rename export file, check gradle project directory for " +"outputs." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Identifier is missing." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "The character '%s' is not allowed in Identifier." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "App Store Team ID not specified - cannot configure the project." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Invalid Identifier:" +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Required icon is not specified in the preset." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Stop HTTP Server" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run in Browser" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run exported HTML in the system's default browser." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not write file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not open template for export:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Invalid export template:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read custom HTML shell:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read boot splash image file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Using default boot splash image." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package short name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package unique name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package publisher display name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid product GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid publisher GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid background color." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid Store Logo image dimensions (should be 50x50)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid splash screen image dimensions (should be 620x300)." +msgstr "" + +#: scene/2d/animated_sprite.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite to display frames." +msgstr "" + +#: scene/2d/canvas_modulate.cpp +msgid "" +"Only one visible CanvasModulate is allowed per scene (or set of instanced " +"scenes). The first created one will work, while the rest will be ignored." +msgstr "" + +#: scene/2d/collision_object_2d.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " +"define its shape." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "" +"CollisionPolygon2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "An empty CollisionPolygon2D has no effect on collision." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"CollisionShape2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"A shape must be provided for CollisionShape2D to function. Please create a " +"shape resource for it!" +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"Polygon-based shapes are not meant be used nor edited directly through the " +"CollisionShape2D node. Please use the CollisionPolygon2D node instead." +msgstr "" + +#: scene/2d/cpu_particles_2d.cpp +msgid "" +"CPUParticles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be PhysicsBody2Ds" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A must be a PhysicsBody2D" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node B must be a PhysicsBody2D" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Joint is not connected to two PhysicsBody2Ds" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be different PhysicsBody2Ds" +msgstr "" + +#: scene/2d/light_2d.cpp +msgid "" +"A texture with the shape of the light must be supplied to the \"Texture\" " +"property." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "" +"An occluder polygon must be set (or drawn) for this occluder to take effect." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"A NavigationPolygon resource must be set or created for this node to work. " +"Please set a property or draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"NavigationPolygonInstance must be a child or grandchild to a Navigation2D " +"node. It only provides navigation data." +msgstr "" + +#: scene/2d/parallax_layer.cpp +msgid "" +"ParallaxLayer node only works when set as child of a ParallaxBackground node." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles2D node instead. You can use the \"Convert to " +"CPUParticles\" option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp scene/3d/particles.cpp +msgid "" +"A material to process the particles is not assigned, so no behavior is " +"imprinted." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"Particles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/path_2d.cpp +msgid "PathFollow2D only works when set as a child of a Path2D node." +msgstr "" + +#: scene/2d/physics_body_2d.cpp +msgid "" +"Size changes to RigidBody2D (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/2d/remote_transform_2d.cpp +msgid "Path property must point to a valid Node2D node to work." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "This Bone2D chain should end at a Skeleton2D node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "" +"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." +msgstr "" + +#: scene/2d/tile_map.cpp +msgid "" +"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes " +"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " +"KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/visibility_notifier_2d.cpp +msgid "" +"VisibilityEnabler2D works best when used with the edited scene root directly " +"as parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRCamera must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRController must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The controller ID must not be 0 or this controller won't be bound to an " +"actual controller." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRAnchor must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The anchor ID must not be 0 or this anchor won't be bound to an actual " +"anchor." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVROrigin requires an ARVRCamera child node." +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Finding meshes and lights" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing geometry (%d/%d)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing environment" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Generating capture" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Done" +msgstr "" + +#: scene/3d/collision_object.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape or CollisionPolygon as a child to define " +"its shape." +msgstr "" + +#: scene/3d/collision_polygon.cpp +msgid "" +"CollisionPolygon only serves to provide a collision shape to a " +"CollisionObject derived node. Please only use it as a child of Area, " +"StaticBody, RigidBody, KinematicBody, etc. to give them a shape." +msgstr "" + +#: scene/3d/collision_polygon.cpp +msgid "An empty CollisionPolygon has no effect on collision." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"CollisionShape only serves to provide a collision shape to a CollisionObject " +"derived node. Please only use it as a child of Area, StaticBody, RigidBody, " +"KinematicBody, etc. to give them a shape." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"A shape must be provided for CollisionShape to function. Please create a " +"shape resource for it." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"Plane shapes don't work well and will be removed in future versions. Please " +"don't use them." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"ConcavePolygonShape doesn't support RigidBody in another mode than static." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "Nothing is visible because no mesh has been assigned." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "" +"CPUParticles animation requires the usage of a SpatialMaterial whose " +"Billboard Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Plotting Meshes" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "" +"GIProbes are not supported by the GLES2 video driver.\n" +"Use a BakedLightmap instead." +msgstr "" + +#: scene/3d/interpolated_camera.cpp +msgid "" +"InterpolatedCamera has been deprecated and will be removed in Godot 4.0." +msgstr "" + +#: scene/3d/light.cpp +msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "A NavigationMesh resource must be set or created for this node to work." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "" +"NavigationMeshInstance must be a child or grandchild to a Navigation node. " +"It only provides navigation data." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" +"\" option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Nothing is visible because meshes have not been assigned to draw passes." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Particles animation requires the usage of a SpatialMaterial whose Billboard " +"Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/path.cpp +msgid "PathFollow only works when set as a child of a Path node." +msgstr "" + +#: scene/3d/path.cpp +msgid "" +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." +msgstr "" + +#: scene/3d/physics_body.cpp +msgid "" +"Size changes to RigidBody (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A must be a PhysicsBody" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node B must be a PhysicsBody" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Joint is not connected to any PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be different PhysicsBodies" +msgstr "" + +#: scene/3d/remote_transform.cpp +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "This body will be ignored until you set a mesh." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "" +"Size changes to SoftBody will be overridden by the physics engine when " +"running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/3d/sprite_3d.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite3D to display frames." +msgstr "" + +#: scene/3d/vehicle_body.cpp +msgid "" +"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " +"it as a child of a VehicleBody." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " +"this environment's Background Mode to Canvas (for 2D scenes)." +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "On BlendTree node '%s', animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "Animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "In node '%s', invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Nothing connected to input '%s' of node '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "No root AnimationNode for the graph is set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path to an AnimationPlayer node containing animations is not set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "The AnimationPlayer root node is not a valid node." +msgstr "" + +#: scene/animation/animation_tree_player.cpp +msgid "This node has been deprecated. Use AnimationTree instead." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "" +"Color: #%s\n" +"LMB: Set color\n" +"RMB: Remove preset" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Pick a color from the editor window." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Switch between hexadecimal and code values." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Add current color as a preset." +msgstr "" + +#: scene/gui/container.cpp +msgid "" +"Container by itself serves no purpose unless a script configures its " +"children placement behavior.\n" +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" + +#: scene/gui/control.cpp +msgid "" +"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to " +"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"." +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Alert!" +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Please Confirm..." +msgstr "" + +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + +#: scene/gui/graph_edit.cpp +msgid "Enable grid minimap." +msgstr "" + +#: scene/gui/popup.cpp +msgid "" +"Popups will hide by default unless you call popup() or any of the popup*() " +"functions. Making them visible for editing is fine, but they will hide upon " +"running." +msgstr "" + +#: scene/gui/range.cpp +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." +msgstr "" + +#: scene/gui/scroll_container.cpp +msgid "" +"ScrollContainer is intended to work with a single child control.\n" +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " +"minimum size manually." +msgstr "" + +#: scene/gui/tree.cpp +msgid "(Other)" +msgstr "" + +#: scene/main/scene_tree.cpp +msgid "" +"Default Environment as specified in Project Settings (Rendering -> " +"Environment -> Default Environment) could not be loaded." +msgstr "" + +#: scene/main/viewport.cpp +msgid "" +"This viewport is not set as render target. If you intend for it to display " +"its contents directly to the screen, make it a child of a Control so it can " +"obtain a size. Otherwise, make it a RenderTarget and assign its internal " +"texture to some node for display." +msgstr "" + +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for preview." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for shader." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid comparison function for that type." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to uniform." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Varyings can only be assigned in vertex function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Constants cannot be modified." +msgstr "" diff --git a/editor/translations/he.po b/editor/translations/he.po index c179d06c24..fc4ba10dc4 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -7392,6 +7392,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index fbf1352eff..08829557bb 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -7244,6 +7244,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "आकार: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index 9826f61488..95f2844a22 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -7078,6 +7078,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 78db184f7d..e774fec26d 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -7282,6 +7282,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Méret: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Rajzolt objektumok" diff --git a/editor/translations/id.po b/editor/translations/id.po index b7dc29eb20..923b836555 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -7360,6 +7360,11 @@ msgid "Yaw" msgstr "Oleng" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Ukuran: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objek Digambar" diff --git a/editor/translations/is.po b/editor/translations/is.po index 88dbd92927..8ab4fd9ec3 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -7139,6 +7139,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index f322366f4f..3bc0ebac67 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -52,15 +52,15 @@ # Anonymous <noreply@weblate.org>, 2020. # riccardo boffelli <riccardo.boffelli.96@gmail.com>, 2020. # Lorenzo Asolan <brixiumx@gmail.com>, 2020. -# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020. +# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020, 2021. # Federico Manzella <ferdiu.manzella@gmail.com>, 2020. # Ziv D <wizdavid@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-22 10:21+0000\n" -"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" +"PO-Revision-Date: 2021-02-01 20:53+0000\n" +"Last-Translator: Lorenzo Cerqua <lorenzocerqua@tutanota.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -472,16 +472,18 @@ msgid "Not possible to add a new track without a root" msgstr "Non è possibile aggiungere una nuova traccia senza un nodo radice" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Invalid track for Bezier (no suitable sub-properties)" -msgstr "Traccia non valida per la curva Bézier (nessuna sottoproprietà adatta)" +msgstr "" +"Traccia non valida per una curva di Bézier (nessuna sotto-proprietà adatta)" #: editor/animation_track_editor.cpp msgid "Add Bezier Track" -msgstr "Aggiungi traccia Bézier" +msgstr "Aggiungi una traccia di curve di Bézier" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "Il tracciato non è valido, non è possibile aggiungere una chiave." +msgstr "La traccia non è valida, quindi è impossibile aggiungere una chiave." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" @@ -489,21 +491,22 @@ msgstr "La traccia non è di tipo Spatial, impossibile aggiungere la chiave" #: editor/animation_track_editor.cpp msgid "Add Transform Track Key" -msgstr "Aggiungi chiave traccia Transform" +msgstr "Aggiungi una chiave a una traccia di trasformazioni" #: editor/animation_track_editor.cpp msgid "Add Track Key" -msgstr "Aggiungi chiave traccia" +msgstr "Aggiungi una chiave a una traccia" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Track path is invalid, so can't add a method key." msgstr "" -"Il tracciato non è valido, non è possibile aggiungere una chiave di chiamata " -"di funzione." +"La traccia non è valida, quindi non è possibile aggiungere una chiave di " +"chiamata di metodo." #: editor/animation_track_editor.cpp msgid "Add Method Track Key" -msgstr "Aggiungi chiave alla traccia metodo" +msgstr "Aggiungi una chiave a una traccia di chiamate di metodi" #: editor/animation_track_editor.cpp msgid "Method not found in object: " @@ -511,7 +514,7 @@ msgstr "Metodo non trovato nell'oggetto: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" -msgstr "Sposta chiavi animazione" +msgstr "Sposta delle chiavi d'animazione" #: editor/animation_track_editor.cpp msgid "Clipboard is empty" @@ -519,20 +522,21 @@ msgstr "Gli appunti sono vuoti" #: editor/animation_track_editor.cpp msgid "Paste Tracks" -msgstr "Incolla tracce" +msgstr "Incolla delle tracce" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "Scala chiavi animazione" +msgstr "Scala delle chiavi d'animazione" #: editor/animation_track_editor.cpp msgid "" "This option does not work for Bezier editing, as it's only a single track." msgstr "" -"Questa opzione non funziona per modificare curve di Bézier, dato che si " -"tratta di una traccia singola." +"Questa opzione non funziona per modificare delle curve di Bézier, dato che " +"si tratta di una singola traccia." #: editor/animation_track_editor.cpp +#, fuzzy msgid "" "This animation belongs to an imported scene, so changes to imported tracks " "will not be saved.\n" @@ -544,14 +548,14 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" -"Questa animazione appartiene a una scena importata, eventuali modifiche alle " -"tracce importate non saranno salvate.\n" +"Quest'animazione appartiene a una scena importata, eventuali modifiche fatte " +"alle tracce importate non verranno salvate.\n" "\n" -"Per abilitare la possibilità di aggiungere ulteriori tracce, vai alle " -"impostazioni di importazione della scena e imposta\n" -"\"Animation > Storage\" su \"Files\", abilita \"Animation > Keep Custom " -"Tracks\", e infine reimporta la scena.\n" -"Altrimenti, usa un preset di importazione che importa le animazioni in file " +"Per abilitare la possibilità di aggiungere ulteriori tracce, andare nelle " +"impostazioni d'importazione della scena, impostare\n" +"\"Animation > Storage\" su \"Files\", attivare \"Animation > Keep Custom " +"Tracks\" e infine reimportare la scena.\n" +"Altrimenti, usare una preimpostazione che importi le animazioni in file " "separati." #: editor/animation_track_editor.cpp @@ -568,11 +572,11 @@ msgstr "Mostra solo le tracce dei nodi selezionati nell'albero." #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." -msgstr "Raggruppa le tracce per nodo o mostra una lista semplice." +msgstr "Raggruppa le tracce per nodo o le visualizza in una lista semplice." #: editor/animation_track_editor.cpp msgid "Snap:" -msgstr "Snap:" +msgstr "Scatto:" #: editor/animation_track_editor.cpp msgid "Animation step value." @@ -599,25 +603,26 @@ msgstr "Modifica" #: editor/animation_track_editor.cpp msgid "Animation properties." -msgstr "Proprietà animazione." +msgstr "Proprietà dell'animazione." #: editor/animation_track_editor.cpp msgid "Copy Tracks" -msgstr "Copia tracce" +msgstr "Copia le tracce" #: editor/animation_track_editor.cpp msgid "Scale Selection" -msgstr "Scala selezione" +msgstr "Scala la selezione" #: editor/animation_track_editor.cpp msgid "Scale From Cursor" -msgstr "Scala da cursore" +msgstr "Scala a partire dal cursore" #: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "Duplica selezione" +msgstr "Duplica la selezione" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Duplicate Transposed" msgstr "Duplica trasposto" @@ -626,20 +631,22 @@ msgid "Delete Selection" msgstr "Elimina la selezione" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Go to Next Step" msgstr "Va' al passo successivo" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Go to Previous Step" msgstr "Va' al passo precedente" #: editor/animation_track_editor.cpp msgid "Optimize Animation" -msgstr "Ottimizza animazione" +msgstr "Ottimizza l'animazione" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation" -msgstr "Pulisci animazione" +msgstr "Pulisci l'animazione" #: editor/animation_track_editor.cpp msgid "Pick the node that will be animated:" @@ -647,7 +654,7 @@ msgstr "Seleziona il nodo che verrà animato:" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" -msgstr "Usa curve di Bézier" +msgstr "Usa le curve di Bézier" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" @@ -655,15 +662,15 @@ msgstr "Ottimizzatore anim." #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" -msgstr "Max. errore lineare:" +msgstr "Max errore lineare:" #: editor/animation_track_editor.cpp msgid "Max. Angular Error:" -msgstr "Max. errore angolare:" +msgstr "Max errore angolare:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "Max. angolo ottimizzabile:" +msgstr "Max angolo ottimizzabile:" #: editor/animation_track_editor.cpp msgid "Optimize" @@ -671,11 +678,11 @@ msgstr "Ottimizza" #: editor/animation_track_editor.cpp msgid "Remove invalid keys" -msgstr "Rimuovi chiavi non valide" +msgstr "Rimuovi le chiavi non valide" #: editor/animation_track_editor.cpp msgid "Remove unresolved and empty tracks" -msgstr "Rimuovi tracce irrisolte e vuote" +msgstr "Rimuovi le tracce irrisolte e vuote" #: editor/animation_track_editor.cpp msgid "Clean-up all animations" @@ -683,7 +690,7 @@ msgstr "Pulisci tutte le animazioni" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "Pulisci animazione(i) (NON ANNULLABILE!)" +msgstr "Pulisci le animazioni (NON ANNULLABILE!)" #: editor/animation_track_editor.cpp msgid "Clean-Up" @@ -708,31 +715,33 @@ msgstr "Copia" #: editor/animation_track_editor.cpp msgid "Select All/None" -msgstr "Seleziona Tutto/Nulla" +msgstr "Seleziona tutto/nulla" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" -msgstr "Aggiungi traccia clip audio" +msgstr "Aggiungi audio in una traccia di riproduzione audio" #: editor/animation_track_editor_plugins.cpp +#, fuzzy msgid "Change Audio Track Clip Start Offset" -msgstr "Cambia Offset di Inizio della Clip della Traccia Audio" +msgstr "Cambia lo scostamento dell'inizio della traccia audio" #: editor/animation_track_editor_plugins.cpp +#, fuzzy msgid "Change Audio Track Clip End Offset" -msgstr "Cambia offset di fine della clip della traccia audio" +msgstr "Cambia lo scostamento della fine della traccia audio" #: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "Ridimensiona array" +msgstr "Ridimensiona lista" #: editor/array_property_edit.cpp msgid "Change Array Value Type" -msgstr "Cambia tipo del valore dell'array" +msgstr "Cambia il tipo del valore della lista" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "Cambia valore array" +msgstr "Cambia il valore della lista" #: editor/code_editor.cpp msgid "Go to Line" @@ -740,7 +749,7 @@ msgstr "Vai alla linea" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "Numero linea:" +msgstr "Numero della linea:" #: editor/code_editor.cpp msgid "%d replaced." @@ -752,11 +761,11 @@ msgstr "%d corrispondenza." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." -msgstr "%d corrispondenza/e." +msgstr "%d corrispondenze." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "Distingui maiuscole" +msgstr "Distingui le maiuscole" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" @@ -7421,6 +7430,11 @@ msgid "Yaw" msgstr "Imbardata" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Dimensione: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Oggetti disegnati" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 917587952a..d960e0cc32 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -7345,6 +7345,11 @@ msgid "Yaw" msgstr "ヨー" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "サイズ: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "æç”»ã•れãŸã‚ªãƒ–ジェクト" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index c35aebac02..81e843c723 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -7307,6 +7307,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 8c15195d24..c5b4f3c701 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -7303,6 +7303,11 @@ msgid "Yaw" msgstr "ìš”" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "í¬ê¸°: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ê·¸ë ¤ì§„ ê°ì²´" diff --git a/editor/translations/lt.po b/editor/translations/lt.po index f8c6d6acc9..c1c872988f 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -7269,6 +7269,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/lv.po b/editor/translations/lv.po index e7abc2a6e7..09379f2903 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -7126,6 +7126,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 33153ba3a5..9c110afb2d 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -7050,6 +7050,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/mk.po b/editor/translations/mk.po index 71da151591..47bb481995 100644 --- a/editor/translations/mk.po +++ b/editor/translations/mk.po @@ -7057,6 +7057,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index a72cd78ca2..0791218b36 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -7066,6 +7066,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index 6f019300ff..2d2ddb2deb 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -7057,6 +7057,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index 2f3e1481a2..e121414574 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -7388,6 +7388,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Saiz: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 90f033ad39..b597c27fe1 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -7732,6 +7732,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Størrelse: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 22b3202945..33362f4e57 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -28,7 +28,7 @@ # rxadmin <r.van.eeghem@gmail.com>, 2018. # Peter Goelst <muis24@gmail.com>, 2019. # Wouter Buckens <wou.buc@gmail.com>, 2019. -# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2019, 2020. +# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2019, 2020, 2021. # jef dered <themen098s@vivaldi.net>, 2019. # Alex H. <sandertjeh13@hotmail.com>, 2019. # edouardgr <edouard.gruyters@gmail.com>, 2019. @@ -47,7 +47,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-12-25 12:29+0000\n" +"PO-Revision-Date: 2021-02-01 20:53+0000\n" "Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -56,7 +56,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2430,7 +2430,7 @@ msgstr "Er is geen startscène ingesteld." #: editor/editor_node.cpp msgid "Save scene before running..." -msgstr "" +msgstr "Scène opslaan voor het afspelen..." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -3758,6 +3758,11 @@ msgid "" "\n" "Do you wish to overwrite them?" msgstr "" +"De volgende bestanden of mappen conflicteren met elementen in '%s':\n" +"\n" +"%s\n" +"\n" +"Wil je deze overschrijven?" #: editor/filesystem_dock.cpp msgid "Renaming file:" @@ -3950,19 +3955,16 @@ msgid "Searching..." msgstr "Aan het zoeken..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d overeenkomst(en) gevonden." +msgstr "%d overeenkomst in %d bestand." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d overeenkomst(en) gevonden." +msgstr "%d overeenkomsten in %d bestand." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d overeenkomst(en) gevonden." +msgstr "%d overeenkomsten in %d bestanden." #: editor/groups_editor.cpp msgid "Add to Group" @@ -5242,9 +5244,8 @@ msgid "Bake Lightmaps" msgstr "Bak Lichtmappen" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "Select lightmap bake file:" -msgstr "Selecteer sjabloonbestand" +msgstr "Selecteer lightmap bake-bestand" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5313,7 +5314,7 @@ msgstr "Maak nieuwe horizontale en verticale gidsen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" -msgstr "" +msgstr "Draaipuntverschuiving van het CanvasItem „%s“ op (%d, %d) zetten" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate %d CanvasItems" @@ -5336,24 +5337,20 @@ msgid "Resize Control \"%s\" to (%d, %d)" msgstr "Control \"%s\" vergrootten tot (%d, %d)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale %d CanvasItems" -msgstr "Schaal CanvasItem" +msgstr "Schaal %d CanvasItems" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale CanvasItem \"%s\" to (%s, %s)" -msgstr "Schaal CanvasItem" +msgstr "Schaal CanvasItem \"%s\" naar (%s, %s)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move %d CanvasItems" -msgstr "Verplaats CanvasItem" +msgstr "Verplaats %d CanvasItems" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move CanvasItem \"%s\" to (%d, %d)" -msgstr "Verplaats CanvasItem" +msgstr "CanvasItem \"%s\" naar (%d, %d) verplaatsen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -6347,9 +6344,8 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "Kan punt alleen plaatsen in een PartikelsMateriaal proces materiaal" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Convert to CPUParticles2D" -msgstr "Zet om in CPUParticles" +msgstr "Omzetten naar CPUParticles2D" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -6640,9 +6636,8 @@ msgid "Move Points" msgstr "Beweeg Punten" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Command: Rotate" -msgstr "Sleep: Roteer" +msgstr "Ctrl: Roteer" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" @@ -6700,14 +6695,12 @@ msgid "Radius:" msgstr "Radius:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Copy Polygon to UV" -msgstr "Creëer Polygon & UV" +msgstr "Kopieer Polygon naar UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Copy UV to Polygon" -msgstr "Naar Polygon2D omzetten" +msgstr "Kopieer UV naar Polygon2D" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Clear UV" @@ -7389,6 +7382,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Grootte: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objecten Getekend" @@ -8253,13 +8251,12 @@ msgid "Paint Tile" msgstr "Teken Tegel" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "" "Shift+LMB: Line Draw\n" "Shift+Command+LMB: Rectangle Paint" msgstr "" -"Shift+LMB: Lijn Tekenen\n" -"Shift+Ctrl+LMB: Vierkant Tekenen" +"Shift+LMB: Lijn tekenen\n" +"Shift+Ctrl+LMB: Vierkant tekenen" #: editor/plugins/tile_map_editor_plugin.cpp msgid "" @@ -8414,23 +8411,20 @@ msgid "Create a new rectangle." msgstr "Creëer nieuwe driehoek." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "New Rectangle" -msgstr "Teken Driehoek" +msgstr "Nieuwe rechthoek" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create a new polygon." msgstr "Nieuwe veelhoek aanmaken." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "New Polygon" -msgstr "Beweeg Polygon" +msgstr "Nieuwe veelhoek" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete Selected Shape" -msgstr "Geselecteerde Verwijderen" +msgstr "Geselecteerde vormen verwijderen" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." @@ -8795,9 +8789,8 @@ msgid "Add Node to Visual Shader" msgstr "VisualShader-knoop toevoegen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Node(s) Moved" -msgstr "Knoop verplaatst" +msgstr "Knoop/knopen verplaatst" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Duplicate Nodes" @@ -8817,9 +8810,8 @@ msgid "Visual Shader Input Type Changed" msgstr "Visuele Shader Invoertype Gewijzigd" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "UniformRef Name Changed" -msgstr "Uniforme naam instellen" +msgstr "UniformRef naam veranderd" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" @@ -9547,7 +9539,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "A reference to an existing uniform." -msgstr "" +msgstr "Een verwijzing naar een bestaande uniform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(Fragment/Light mode only) Scalar derivative function." @@ -9914,7 +9906,7 @@ msgstr "OpenGL ES 3.0" #: editor/project_manager.cpp msgid "Not supported by your GPU drivers." -msgstr "" +msgstr "Niet ondersteund door de GPU drivers op dit systeem." #: editor/project_manager.cpp msgid "" @@ -10524,19 +10516,16 @@ msgid "Batch Rename" msgstr "Bulk hernoemen" #: editor/rename_dialog.cpp -#, fuzzy msgid "Replace:" -msgstr "Vervangen: " +msgstr "Vervangen:" #: editor/rename_dialog.cpp -#, fuzzy msgid "Prefix:" -msgstr "Voorvoegsel" +msgstr "Voorvoegsel:" #: editor/rename_dialog.cpp -#, fuzzy msgid "Suffix:" -msgstr "Achtervoegsel" +msgstr "Achtervoegsel:" #: editor/rename_dialog.cpp msgid "Use Regular Expressions" @@ -10583,11 +10572,10 @@ msgid "Per-level Counter" msgstr "Per niveau teller" #: editor/rename_dialog.cpp -#, fuzzy msgid "If set, the counter restarts for each group of child nodes." msgstr "" -"Indien ingesteld: herstart de teller voor iedere groep van onderliggende " -"knopen" +"Indien ingesteld, zal de teller voor iedere groep van onderliggende knopen " +"opnieuw starten." #: editor/rename_dialog.cpp msgid "Initial value for the counter" @@ -10646,9 +10634,8 @@ msgid "Reset" msgstr "Resetten" #: editor/rename_dialog.cpp -#, fuzzy msgid "Regular Expression Error:" -msgstr "Fout in reguliere expressie" +msgstr "Fout in reguliere expressie:" #: editor/rename_dialog.cpp msgid "At character %s" @@ -11653,36 +11640,31 @@ msgstr "Voeg een MeshLibrary aan deze GridMap toe om meshes te gebruiken." #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Begin Bake" -msgstr "" +msgstr "Begin lichtberekening" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Preparing data structures" -msgstr "" +msgstr "Datastructuren worden voorbereid" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Generate buffers" -msgstr "Genereer AABB" +msgstr "Genereer buffers" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Direct lighting" -msgstr "Richtingen" +msgstr "Directe verlichting" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Indirect lighting" -msgstr "Rechts Inspringen" +msgstr "Indirecte verlichting" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Post processing" -msgstr "Post-Process" +msgstr "Nabewerking" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Plotting lightmaps" -msgstr "Plotten Light:" +msgstr "Lightmaps plotten" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -12202,7 +12184,7 @@ msgstr "Selecteer apparaat uit de lijst" #: platform/android/export/export.cpp msgid "Unable to find the 'apksigner' tool." -msgstr "" +msgstr "Het hulpmiddel 'apksigner' kon niet gevonden worden." #: platform/android/export/export.cpp msgid "" @@ -12221,18 +12203,17 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "Release-Keystore is verkeerd ingesteld in de exportinstelingen." #: platform/android/export/export.cpp -#, fuzzy msgid "A valid Android SDK path is required in Editor Settings." -msgstr "Ongeldig Android SDK pad voor custom build in Editor Settings." +msgstr "" +"Een geldig Android SDK-pad moet in de Editorinstellingen ingesteld zijn." #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid Android SDK path in Editor Settings." -msgstr "Ongeldig Android SDK pad voor custom build in Editor Settings." +msgstr "Ongeldig Android SDK-pad in Editorinstellingen." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" -msgstr "" +msgstr "'platform-tools' map ontbreekt!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK platform-tools' adb command." diff --git a/editor/translations/or.po b/editor/translations/or.po index c1bc32d40f..334b5b903e 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -7056,6 +7056,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 6372cedd0a..9d783625b9 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -50,8 +50,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-26 03:28+0000\n" -"Last-Translator: gnu-ewm <gnu.ewm@protonmail.com>\n" +"PO-Revision-Date: 2021-02-01 20:54+0000\n" +"Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" "Language: pl\n" @@ -7361,6 +7361,11 @@ msgid "Yaw" msgstr "Odchylenie" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Rozmiar: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Narysowane obiekty" @@ -10154,15 +10159,15 @@ msgstr "Indeks przycisku myszy:" #: editor/project_settings_editor.cpp msgid "Left Button" -msgstr "Lewy guzik" +msgstr "Lewy przycisk" #: editor/project_settings_editor.cpp msgid "Right Button" -msgstr "Prawy guzik" +msgstr "Prawy przycisk" #: editor/project_settings_editor.cpp msgid "Middle Button" -msgstr "Åšrodkowy guzik" +msgstr "Åšrodkowy przycisk" #: editor/project_settings_editor.cpp msgid "Wheel Up Button" @@ -12160,18 +12165,12 @@ msgstr "" "Wydaniowy keystore jest niepoprawnie skonfigurowany w profilu eksportu." #: platform/android/export/export.cpp -#, fuzzy msgid "A valid Android SDK path is required in Editor Settings." -msgstr "" -"Niepoprawna Å›cieżka do SDK Androida dla wÅ‚asnego builda w Ustawieniach " -"Edytora." +msgstr "Wymagana jest poprawna Å›cieżka SDK Androida w Ustawieniach Edytora." #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid Android SDK path in Editor Settings." -msgstr "" -"Niepoprawna Å›cieżka do SDK Androida dla wÅ‚asnego builda w Ustawieniach " -"Edytora." +msgstr "Niepoprawna Å›cieżka do SDK Androida w Ustawieniach Edytora." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" @@ -12180,13 +12179,11 @@ msgstr "Folder \"platform-tools\" nie istnieje!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK platform-tools' adb command." msgstr "" +"Nie udaÅ‚o siÄ™ znaleźć komendy adb z narzÄ™dzi platformowych SDK Androida." #: platform/android/export/export.cpp -#, fuzzy msgid "Please check in the Android SDK directory specified in Editor Settings." -msgstr "" -"Niepoprawna Å›cieżka do SDK Androida dla wÅ‚asnego builda w Ustawieniach " -"Edytora." +msgstr "Sprawdź w folderze SDK Androida podanych w Ustawieniach Edytora." #: platform/android/export/export.cpp msgid "Missing 'build-tools' directory!" @@ -12194,7 +12191,7 @@ msgstr "Brakuje folderu \"build-tools\"!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK build-tools' apksigner command." -msgstr "" +msgstr "Nie udaÅ‚o siÄ™ znaleźć komendy apksigner z narzÄ™dzi SDK Androida." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12672,27 +12669,23 @@ msgstr "ARVROrigin wymaga wÄ™zÅ‚a potomnego typu ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" -msgstr "" +msgstr "Szukanie siatek i Å›wiateÅ‚" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing geometry (%d/%d)" -msgstr "Parsowanie Geometrii..." +msgstr "Przygotowywanie geometrii (%d/%d)" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing environment" -msgstr "WyÅ›wietlaj Å›rodowisko" +msgstr "Przygotowywanie Å›rodowiska" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generating capture" -msgstr "Generowanie Lightmapy" +msgstr "Generowanie przechwycenia" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Saving lightmaps" -msgstr "Generowanie Lightmapy" +msgstr "Zapisywanie map Å›wiatÅ‚a" #: scene/3d/baked_lightmap.cpp msgid "Done" @@ -13099,6 +13092,8 @@ msgid "" "The sampler port is connected but not used. Consider changing the source to " "'SamplerPort'." msgstr "" +"Port samplera jest podłączony, ale nieużyty. Rozważ zmianÄ™ źródÅ‚a na " +"\"SamplerPort\"." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 9f6933a077..f8ea72a750 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -7293,6 +7293,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/pt.po b/editor/translations/pt.po index 24cd684ee9..0d3524786b 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -7334,6 +7334,11 @@ msgid "Yaw" msgstr "Direção" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamanho: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos desenhados" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 1e099e065c..b20cc35809 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -110,11 +110,13 @@ # Lucas Dantas <lucas.lucantas38@gmail.com>, 2021. # Carlos Bonifacio <carlosboni.sa@gmail.com>, 2021. # Lucas Castro <castroclucas@gmail.com>, 2021. +# Ricardo Zamarrenho Carvalho Correa <ricardozcc17@gmail.com>, 2021. +# Diego dos Reis Macedo <diego_dragon97@hotmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2021-01-26 03:28+0000\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" "Last-Translator: Lucas Castro <castroclucas@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" @@ -7443,6 +7445,11 @@ msgid "Yaw" msgstr "Guinada" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Tamanho: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Objetos Desenhados" @@ -11679,8 +11686,9 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes." msgstr "Atribua um recurso MeshLibrary a este GridMap para usar seus meshes." #: modules/lightmapper_cpu/lightmapper_cpu.cpp +#, fuzzy msgid "Begin Bake" -msgstr "" +msgstr "Iniciar pré-cálculo" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Preparing data structures" @@ -11695,19 +11703,18 @@ msgid "Direct lighting" msgstr "Direct lightning" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Indirect lighting" -msgstr "Recuar Direita" +msgstr "Iluminação indireta" #: modules/lightmapper_cpu/lightmapper_cpu.cpp #, fuzzy msgid "Post processing" -msgstr "Pós-Processamento" +msgstr "Pós-processamento" #: modules/lightmapper_cpu/lightmapper_cpu.cpp #, fuzzy msgid "Plotting lightmaps" -msgstr "Planejando Luzes:" +msgstr "Traçando mapas de luz" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -12249,18 +12256,12 @@ msgstr "" "exportação." #: platform/android/export/export.cpp -#, fuzzy msgid "A valid Android SDK path is required in Editor Settings." -msgstr "" -"Caminho do Android SDK inválido para o build personalizado em Configurações " -"do Editor." +msgstr "Um caminho Android SDK é necessário nas Configurações do Editor." #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid Android SDK path in Editor Settings." -msgstr "" -"Caminho do Android SDK inválido para o build personalizado em Configurações " -"do Editor." +msgstr "Caminho do Android SDK está inválido para Configurações do Editor." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" @@ -12272,16 +12273,14 @@ msgstr "" "Não foi possÃvel encontrar o comando adb nas ferramentas do Android SDK." #: platform/android/export/export.cpp -#, fuzzy msgid "Please check in the Android SDK directory specified in Editor Settings." msgstr "" -"Caminho do Android SDK inválido para o build personalizado em Configurações " +"Por favor, verifique o caminho do Android SDK especificado nas Configurações " "do Editor." #: platform/android/export/export.cpp -#, fuzzy msgid "Missing 'build-tools' directory!" -msgstr "Diretório 'ferramentas-da-plataforma' ausente!" +msgstr "Diretório 'ferramentas-da-plataforma' está faltando !" #: platform/android/export/export.cpp msgid "Unable to find Android SDK build-tools' apksigner command." @@ -12765,19 +12764,17 @@ msgid "Preparing geometry (%d/%d)" msgstr "Analisando Geometria..." #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing environment" -msgstr "Visualizar Ambiente" +msgstr "Preparando ambiente" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generating capture" -msgstr "Generando Lightmaps" +msgstr "Gerando captura" #: scene/3d/baked_lightmap.cpp #, fuzzy msgid "Saving lightmaps" -msgstr "Generando Lightmaps" +msgstr "Salvando mapas de luz" #: scene/3d/baked_lightmap.cpp msgid "Done" @@ -13123,9 +13120,8 @@ msgid "Must use a valid extension." msgstr "Deve usar uma extensão válida." #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Ativar Snap" +msgstr "Ativar minimapa de grade." #: scene/gui/popup.cpp msgid "" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 8cdaef5b59..100afe3cb9 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -7427,6 +7427,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index 122e75352d..61f4d23157 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -95,7 +95,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-21 08:48+0000\n" +"PO-Revision-Date: 2021-02-01 20:54+0000\n" "Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -5727,7 +5727,7 @@ msgstr "ОчиÑтить пользовательÑкие коÑти" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "Обзор" +msgstr "Вид" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Always Show Grid" @@ -5767,7 +5767,7 @@ msgstr "Кадрировать выбранное" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "ПроÑмотреть Canvas Scale" +msgstr "ПредпроÑмотр Canvas Scale" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -7408,6 +7408,11 @@ msgid "Yaw" msgstr "Ð Ñ‹Ñкание" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Размер: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ÐариÑовано обьектов" diff --git a/editor/translations/si.po b/editor/translations/si.po index 46e606d935..e7aabd5542 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -3,12 +3,13 @@ # Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. # Yohan Sandun <Yohan99ysk@gmail.com>, 2018. +# thushariii <thusharipahalage@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-12-13 14:42+0100\n" -"Last-Translator: Yohan Sandun <Yohan99ysk@gmail.com>\n" +"PO-Revision-Date: 2021-02-05 09:20+0000\n" +"Last-Translator: thushariii <thusharipahalage@gmail.com>\n" "Language-Team: Sinhala <https://hosted.weblate.org/projects/godot-engine/" "godot/si/>\n" "Language: si\n" @@ -16,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -103,11 +104,11 @@ msgstr "à¶šà·à¶©à¶´à¶" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" -msgstr "" +msgstr "à¶šà·à¶½à¶º:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "වටිනà·à¶šà¶¸:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -190,7 +191,7 @@ msgstr "සජීවීකරණ පුනරà·à·€à¶»à·Šà¶®à¶±à¶º" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation Loop" -msgstr "" +msgstr "සජීවිකරණ ලූපය වෙනස් කරන්න" #: editor/animation_track_editor.cpp msgid "Property Track" @@ -249,7 +250,7 @@ msgstr "Anim පසුරු:" #: editor/animation_track_editor.cpp msgid "Change Track Path" -msgstr "" +msgstr "පථය වෙනස් කරන්න" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." @@ -331,7 +332,7 @@ msgstr "යà¶à·”රු මක෠දමන්න" #: editor/animation_track_editor.cpp msgid "Change Animation Update Mode" -msgstr "" +msgstr "සජීවිකරණ යà·à·€à¶à·Šà¶šà·à¶½à·“à¶± à¶´à·Šâ€à¶»à¶šà·à¶»à¶º වෙනස් කරන්න" #: editor/animation_track_editor.cpp #, fuzzy @@ -435,7 +436,7 @@ msgstr "ලුහුබදින්නෙක් à¶‘à¶šà·Š කරන්න" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "" +msgstr "පථය අවලංගු à¶¶à·à·€à·’න් යà¶à·”රක් à¶‘à¶šà·Š à¶šà·… නොහà·à¶š." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" @@ -7109,6 +7110,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index c9133c8d7c..c7839822c9 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -7321,6 +7321,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "VeľkosÅ¥: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index a953258d3f..ee152a25a3 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -12,12 +12,13 @@ # Arnold Marko <arnold.marko@gmail.com>, 2019. # Alex <alexrixhardson@gmail.com>, 2019. # Andrew Poženel <andrej.pozenel@outlook.com>, 2020. +# Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-07-15 02:42+0000\n" -"Last-Translator: Andrew Poženel <andrej.pozenel@outlook.com>\n" +"PO-Revision-Date: 2021-02-01 20:54+0000\n" +"Last-Translator: Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>\n" "Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/" "godot/sl/>\n" "Language: sl\n" @@ -26,7 +27,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" "%100==4 ? 2 : 3;\n" -"X-Generator: Weblate 4.2-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -370,7 +371,7 @@ msgstr "Odstrani animacijsko sled" #: editor/animation_track_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "Ustvarim NOVO sled za %s in vstavim kljuÄ?" +msgstr "Ustvarim NOVO sled za %s in vstavi kljuÄ?" #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" @@ -7626,6 +7627,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index 7dcc32735d..90905673c2 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -7380,6 +7380,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Madhësia: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index b07bc4e1c9..eea195210a 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -8041,6 +8041,11 @@ msgid "Yaw" msgstr "Горе-Доле" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Величина:" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Ðацртани објекти" diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index 232c53da80..9a88a06a25 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -7153,6 +7153,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index cab4b7e5bc..9f812d7b8f 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -7515,6 +7515,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/ta.po b/editor/translations/ta.po index 45de03bdb3..b933fe6052 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -7114,6 +7114,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/te.po b/editor/translations/te.po index aa703812fe..e0ec4b5534 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -7059,6 +7059,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index 4b1d938c54..8e083aef79 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -7213,6 +7213,11 @@ msgid "Yaw" msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "ขนาด: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "à¸à¸à¸šà¹€à¸ˆà¸à¸•์ที่วาด" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 867a66b3dc..71379593fd 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -7371,6 +7371,11 @@ msgid "Yaw" msgstr "Yalpala" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Boyut: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "ÇizilmiÅŸ Nesneler" diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po index 7853cd3b8c..ef86476e21 100644 --- a/editor/translations/tzm.po +++ b/editor/translations/tzm.po @@ -7057,6 +7057,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index 75da46cdc4..31aa7794a7 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -7360,6 +7360,11 @@ msgid "Yaw" msgstr "ВідхиленнÑ" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "Розмір: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "Ðамальовано об'єктів" diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index c7722c84c4..bf95b4c01f 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -7218,6 +7218,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 97c2be742e..c08fca86dd 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -7366,6 +7366,11 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "KÃch thước: " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index 2c46f95dc0..938981d022 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -58,7 +58,7 @@ # idleman <1524328475@qq.com>, 2019. # king <wangding1992@126.com>, 2019. # silentbird <silentbird520@outlook.com>, 2019. -# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020. +# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021. # Revan Ji <jiruifancr@gmail.com>, 2020. # nieyuanhong <15625988003@163.com>, 2020. # binotaliu <binota@protonmail.ch>, 2020. @@ -74,12 +74,13 @@ # BinotaLIU <me@binota.org>, 2020. # TakWolf <takwolf@foxmail.com>, 2020. # twoBornottwoB <305766341@qq.com>, 2021. +# Magian <magian1127@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2021-01-22 10:21+0000\n" -"Last-Translator: twoBornottwoB <305766341@qq.com>\n" +"PO-Revision-Date: 2021-01-27 23:21+0000\n" +"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -3773,7 +3774,7 @@ msgstr "全部折å " #: editor/filesystem_dock.cpp msgid "Duplicate..." -msgstr "é‡å¤..." +msgstr "å¤åˆ¶ä¸º..." #: editor/filesystem_dock.cpp msgid "Move to Trash" @@ -5119,7 +5120,6 @@ msgid "Assets ZIP File" msgstr "ç´ æ ZIP 文件" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" "Save your scene and try again." @@ -5140,18 +5140,18 @@ msgstr "åˆ›å»ºå…‰ç…§è´´å›¾å¤±è´¥ï¼Œåˆ‡ç¡®ä¿æ–‡ä»¶æ˜¯å¯å†™çš„。" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed determining lightmap size. Maximum lightmap size too small?" -msgstr "" +msgstr "æ— æ³•ç¡®å®šå…‰ç…§è´´å›¾å¤§å°ã€‚最大光照贴图大å°å¤ªå°ï¼Ÿ" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Some mesh is invalid. Make sure the UV2 channel values are contained within " "the [0.0,1.0] square region." -msgstr "" +msgstr "æŸäº›ç½‘æ ¼æ— æ•ˆã€‚ç¡®ä¿UV2通é“值包å«åœ¨[0.0,1.0]平方区域内。" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." -msgstr "" +msgstr "Godot编辑器是在没有光线跟踪支æŒçš„æƒ…å†µä¸‹æž„å»ºçš„ï¼Œå…‰ç…§è´´å›¾æ— æ³•çƒ˜ç„™ã€‚" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" @@ -5159,7 +5159,7 @@ msgstr "烘焙光照贴图" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Select lightmap bake file:" -msgstr "é€‰æ‹©æ¨¡æ¿æ–‡ä»¶ï¼š" +msgstr "选择光照贴图烘焙文件:" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6239,9 +6239,8 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "åªå¯è®¾ä¸ºæŒ‡å‘ ParticlesMaterial å¤„ç†ææ–™" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Convert to CPUParticles2D" -msgstr "转æ¢ä¸º CPUParticles" +msgstr "转æ¢ä¸ºCPUParticles2D" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -7266,6 +7265,11 @@ msgid "Yaw" msgstr "å航角" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "大å°ï¼š " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "绘制对象" @@ -11425,35 +11429,31 @@ msgstr "呿¤ GridMap æä¾›ç½‘æ ¼åº“èµ„æºä»¥ä½¿ç”¨å…¶ç½‘æ ¼ã€‚" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Begin Bake" -msgstr "" +msgstr "开始烘焙" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Preparing data structures" -msgstr "" +msgstr "准备数æ®ç»“æž„" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Generate buffers" -msgstr "ç”Ÿæˆ AABB" +msgstr "生æˆç¼“冲区" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Direct lighting" -msgstr "æ–¹å‘" +msgstr "直接照明" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Indirect lighting" -msgstr "å‘å³ç¼©è¿›" +msgstr "间接照明" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Post processing" -msgstr "åŽæœŸå¤„ç†" +msgstr "åŽå¤„ç†" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Plotting lightmaps" -msgstr "æ£åœ¨ç»˜åˆ¶ç¯å…‰" +msgstr "绘制光照图" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -11954,9 +11954,8 @@ msgid "Select device from the list" msgstr "从列表ä¸é€‰æ‹©è®¾å¤‡" #: platform/android/export/export.cpp -#, fuzzy msgid "Unable to find the 'apksigner' tool." -msgstr "未找到 zipalign 工具。" +msgstr "找ä¸åˆ°â€œapksignerâ€å·¥å…·ã€‚" #: platform/android/export/export.cpp msgid "" @@ -11973,14 +11972,12 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "用于å‘布的密钥å˜å‚¨åœ¨å¯¼å‡ºé¢„è®¾ä¸æœªè¢«æ£ç¡®è®¾ç½®ã€‚" #: platform/android/export/export.cpp -#, fuzzy msgid "A valid Android SDK path is required in Editor Settings." -msgstr "用于 “编辑器设置†ä¸è‡ªå®šä¹‰æž„建的 Android SDK è·¯å¾„æ˜¯æ— æ•ˆçš„ã€‚" +msgstr "编辑器设置ä¸éœ€è¦æœ‰æ•ˆçš„Android SDK路径。" #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid Android SDK path in Editor Settings." -msgstr "用于 “编辑器设置†ä¸è‡ªå®šä¹‰æž„建的 Android SDK è·¯å¾„æ˜¯æ— æ•ˆçš„ã€‚" +msgstr "编辑器设置ä¸çš„Android SDKè·¯å¾„æ— æ•ˆã€‚" #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" @@ -11988,12 +11985,11 @@ msgstr "缺失“platform-toolsâ€ç›®å½•ï¼" #: platform/android/export/export.cpp msgid "Unable to find Android SDK platform-tools' adb command." -msgstr "" +msgstr "找ä¸åˆ°Android SDKå¹³å°å·¥å…·çš„adb命令。" #: platform/android/export/export.cpp -#, fuzzy msgid "Please check in the Android SDK directory specified in Editor Settings." -msgstr "用于 “编辑器设置†ä¸è‡ªå®šä¹‰æž„建的 Android SDK è·¯å¾„æ˜¯æ— æ•ˆçš„ã€‚" +msgstr "请ç¾å…¥ç¼–è¾‘å™¨è®¾ç½®ä¸æŒ‡å®šçš„Android SDK目录。" #: platform/android/export/export.cpp msgid "Missing 'build-tools' directory!" @@ -12001,7 +11997,7 @@ msgstr "缺失“build-toolsâ€ç›®å½•ï¼" #: platform/android/export/export.cpp msgid "Unable to find Android SDK build-tools' apksigner command." -msgstr "" +msgstr "找ä¸åˆ°Android SDK生æˆå·¥å…·çš„apksigner命令。" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12431,27 +12427,23 @@ msgstr "ARVROrigin 需è¦ä¸€ä¸ª ARVRCamera å节点。" #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" -msgstr "" +msgstr "æ£åœ¨æŸ¥æ‰¾ç½‘æ ¼å’Œç¯å…‰" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing geometry (%d/%d)" -msgstr "è§£æžå¤šè¾¹å½¢ä¸..." +msgstr "æ£åœ¨å‡†å¤‡å‡ 何体(%d/%d)" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing environment" -msgstr "查看环境" +msgstr "æ£åœ¨å‡†å¤‡çŽ¯å¢ƒ" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generating capture" -msgstr "æ£åœ¨ç”Ÿæˆå…‰ç…§è´´å›¾" +msgstr "æ£åœ¨ç”Ÿæˆæ•获" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Saving lightmaps" -msgstr "æ£åœ¨ç”Ÿæˆå…‰ç…§è´´å›¾" +msgstr "æ£åœ¨ä¿å˜å…‰ç…§è´´å›¾" #: scene/3d/baked_lightmap.cpp msgid "Done" @@ -12833,7 +12825,7 @@ msgstr "Viewport 大å°å¤§äºŽ 0 æ—¶æ‰èƒ½è¿›è¡Œæ¸²æŸ“。" msgid "" "The sampler port is connected but not used. Consider changing the source to " "'SamplerPort'." -msgstr "" +msgstr "é‡‡æ ·å™¨ç«¯å£å·²è¿žæŽ¥ä½†æœªä½¿ç”¨ã€‚è€ƒè™‘å°†æºæ›´æ”¹ä¸ºâ€œSamplerPortâ€ã€‚" #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index 99d673b0fa..70487c165e 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -7569,6 +7569,10 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index a1228463b9..1dbca29941 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -29,7 +29,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-01 10:30+0000\n" +"PO-Revision-Date: 2021-01-27 23:21+0000\n" "Last-Translator: BinotaLIU <me@binota.org>\n" "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hant/>\n" @@ -38,7 +38,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2364,7 +2364,7 @@ msgstr "æœªå®šç¾©æ¬²åŸ·è¡Œä¹‹å ´æ™¯ã€‚" #: editor/editor_node.cpp msgid "Save scene before running..." -msgstr "" +msgstr "執行å‰å…ˆä¿å˜å ´æ™¯..." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -5072,14 +5072,12 @@ msgid "Assets ZIP File" msgstr "ç´ æ ZIP 檔" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" "Save your scene and try again." msgstr "" "無法判斷光照圖的ä¿å˜è·¯å¾‘。\n" -"è«‹ä¿å˜å ´æ™¯ï¼ˆåœ–片將ä¿å˜æ–¼ç›¸åŒè³‡æ–™å¤¾ï¼‰ï¼Œæˆ–是在 BackedLightmap å±¬æ€§å…§é¸æ“‡ä¸€å€‹ä¿" -"å˜è·¯å¾‘。" +"è«‹ä¿å˜å ´æ™¯ä¸¦é‡è©¦ã€‚" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5094,27 +5092,27 @@ msgstr "建立光照圖失敗,請確ä¿è©²è·¯å¾‘å¯å¯«å…¥ã€‚" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed determining lightmap size. Maximum lightmap size too small?" -msgstr "" +msgstr "無法判斷光照圖大å°ã€‚æœ€å¤§å…‰ç…§åœ–å¤§å°æ˜¯å¦éŽå°ï¼Ÿ" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Some mesh is invalid. Make sure the UV2 channel values are contained within " "the [0.0,1.0] square region." -msgstr "" +msgstr "éƒ¨åˆ†ç¶²æ ¼ç„¡æ•ˆã€‚è«‹ç¢ºä¿ UV2 通é“çš„å€¼ä½æ–¼ [0.0,1.0] 矩形內。" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" +"Godot 編輯器在建制時未啟用光線追蹤 (Ray Tracing) 支æ´ï¼Œç„¡æ³•烘焙光照圖。" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" msgstr "烘焙光照圖" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "Select lightmap bake file:" -msgstr "鏿“‡æ¨£æ¿æª”案" +msgstr "鏿“‡å…‰ç…§åœ–烘焙檔案:" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6194,9 +6192,8 @@ msgid "Can only set point into a ParticlesMaterial process material" msgstr "僅å¯è¨ç‚ºæŒ‡å‘ ProticlesMaterial è™•ç†ææ–™" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Convert to CPUParticles2D" -msgstr "轉æ›ç‚º CPUParticles" +msgstr "轉æ›ç‚º CPUParticles2D" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -7221,6 +7218,11 @@ msgid "Yaw" msgstr "å航" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Size" +msgstr "大å°ï¼š " + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" msgstr "繪製的物件" @@ -11380,36 +11382,31 @@ msgstr "æä¾› MeshLibrary 予該 GridMap ä»¥ä½¿ç”¨å…¶ç¶²æ ¼ã€‚" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Begin Bake" -msgstr "" +msgstr "開始烘焙" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Preparing data structures" -msgstr "" +msgstr "æ£åœ¨æº–å‚™è³‡æ–™çµæ§‹" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Generate buffers" -msgstr "產生 AABB" +msgstr "產生緩è¡" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Direct lighting" -msgstr "æ–¹å‘" +msgstr "呿€§å…‰ç…§" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Indirect lighting" -msgstr "å‘å³ç¸®æŽ’" +msgstr "éžå‘性光照" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Post processing" msgstr "後處ç†" #: modules/lightmapper_cpu/lightmapper_cpu.cpp -#, fuzzy msgid "Plotting lightmaps" -msgstr "æ£åœ¨ç¹ªè£½å…‰ç…§ï¼š" +msgstr "æ£åœ¨ç¹ªè£½å…‰ç…§" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" @@ -11909,9 +11906,8 @@ msgid "Select device from the list" msgstr "自清單ä¸é¸æ“‡è£ç½®" #: platform/android/export/export.cpp -#, fuzzy msgid "Unable to find the 'apksigner' tool." -msgstr "找ä¸åˆ° zipalign 工具。" +msgstr "找ä¸åˆ°ã€Œapksignerã€å·¥å…·ã€‚" #: platform/android/export/export.cpp msgid "" @@ -11928,14 +11924,12 @@ msgid "Release keystore incorrectly configured in the export preset." msgstr "發行金鑰儲å˜å€ä¸ä¸æ£ç¢ºä¹‹çµ„æ…‹è¨å®šè‡³åŒ¯å‡ºé è¨è¨å®šã€‚" #: platform/android/export/export.cpp -#, fuzzy msgid "A valid Android SDK path is required in Editor Settings." -msgstr "編輯器è¨å®šä¸ç”¨æ–¼è‡ªå®šç¾©è¨å®šä¹‹ Android SDK 路徑無效。" +msgstr "å¿…é ˆæ–¼ [編輯器è¨å®š] ä¸æä¾›ä¸€å€‹æœ‰æ•ˆçš„ Android SDK 路徑。" #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid Android SDK path in Editor Settings." -msgstr "編輯器è¨å®šä¸ç”¨æ–¼è‡ªå®šç¾©è¨å®šä¹‹ Android SDK 路徑無效。" +msgstr "[編輯器è¨å®š] 䏿‰€æŒ‡å®šçš„ Android SDK 路徑無效。" #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" @@ -11943,12 +11937,11 @@ msgstr "缺少「platform-toolsã€è³‡æ–™å¤¾ï¼" #: platform/android/export/export.cpp msgid "Unable to find Android SDK platform-tools' adb command." -msgstr "" +msgstr "找ä¸åˆ° Android SDK platform-tools çš„ adb 指令。" #: platform/android/export/export.cpp -#, fuzzy msgid "Please check in the Android SDK directory specified in Editor Settings." -msgstr "編輯器è¨å®šä¸ç”¨æ–¼è‡ªå®šç¾©è¨å®šä¹‹ Android SDK 路徑無效。" +msgstr "請檢查 [編輯器è¨å®š] 䏿‰€æŒ‡å®šçš„ Android SDK 資料夾。" #: platform/android/export/export.cpp msgid "Missing 'build-tools' directory!" @@ -11956,7 +11949,7 @@ msgstr "缺少「build-toolsã€è³‡æ–™å¤¾ï¼" #: platform/android/export/export.cpp msgid "Unable to find Android SDK build-tools' apksigner command." -msgstr "" +msgstr "找ä¸åˆ° Android SDK build-tools çš„ apksigner 指令。" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -12391,32 +12384,27 @@ msgstr "ARVROrigin å¿…é ˆæœ‰ä¸€å€‹ ARVRCamera å節點。" #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" -msgstr "" +msgstr "æ£åœ¨å°‹æ‰¾ç¶²æ ¼èˆ‡å…‰ç…§" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing geometry (%d/%d)" -msgstr "æ£åœ¨è§£æžå¤šé‚Šå½¢..." +msgstr "æ£åœ¨è§£æžå¹¾ä½• (%d/%d)" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Preparing environment" -msgstr "檢視環境" +msgstr "æ£åœ¨æº–備環境" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generating capture" -msgstr "æ£åœ¨ç”¢ç”Ÿå…‰ç…§åœ–" +msgstr "æ£åœ¨ç”¢ç”Ÿæ•æ‰" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Saving lightmaps" -msgstr "æ£åœ¨ç”¢ç”Ÿå…‰ç…§åœ–" +msgstr "æ£åœ¨ä¿å˜å…‰ç…§åœ–" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Done" -msgstr "完æˆï¼" +msgstr "完æˆ" #: scene/3d/collision_object.cpp msgid "" @@ -12794,7 +12782,7 @@ msgstr "Viewport 大å°å¿…é ˆå¤§æ–¼ 0 æ‰å¯é€²è¡Œç®—繪。" msgid "" "The sampler port is connected but not used. Consider changing the source to " "'SamplerPort'." -msgstr "" +msgstr "å·²é€£ç·šè‡³å–æ¨£å™¨é€£çµåŸ 但並未使用。建è°å°‡ä¾†æºè¨ç‚ºã€ŒSamplerPortã€ã€‚" #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/main/main.cpp b/main/main.cpp index 657a6ad822..9489774dce 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -71,7 +71,6 @@ #include "servers/physics_server_3d.h" #include "servers/register_server_types.h" #include "servers/rendering/rendering_server_default.h" -#include "servers/rendering/rendering_server_wrap_mt.h" #include "servers/text_server.h" #include "servers/xr_server.h" @@ -1570,12 +1569,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { /* Initialize Visual Server */ - rendering_server = memnew(RenderingServerDefault); - if (OS::get_singleton()->get_render_thread_mode() != OS::RENDER_THREAD_UNSAFE) { - rendering_server = memnew(RenderingServerWrapMT(rendering_server, - OS::get_singleton()->get_render_thread_mode() == - OS::RENDER_SEPARATE_THREAD)); - } + rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD)); rendering_server->init(); rendering_server->set_render_loop_enabled(!disable_render_loop); @@ -1634,7 +1628,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { register_server_types(); - MAIN_PRINT("Main: Load Remaps"); + MAIN_PRINT("Main: Load Boot Image"); Color clear = GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3)); RenderingServer::get_singleton()->set_default_clear_color(clear); @@ -1690,7 +1684,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: DCC"); RenderingServer::get_singleton()->set_default_clear_color( GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3))); - MAIN_PRINT("Main: END"); GLOBAL_DEF("application/config/icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", @@ -1728,7 +1721,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) { id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input_devices/pointing/emulate_mouse_from_touch", true))); } - MAIN_PRINT("Main: Load Remaps"); + MAIN_PRINT("Main: Load Translations and Remaps"); + + translation_server->setup(); //register translations, load them, etc. + if (locale != "") { + translation_server->set_locale(locale); + } + translation_server->load_translations(); + ResourceLoader::load_translation_remaps(); //load remaps for resources + + ResourceLoader::load_path_remaps(); MAIN_PRINT("Main: Load Scene Types"); @@ -1774,17 +1776,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // This loads global classes, so it must happen before custom loaders and savers are registered ScriptServer::init_languages(); - MAIN_PRINT("Main: Load Translations"); - - translation_server->setup(); //register translations, load them, etc. - if (locale != "") { - translation_server->set_locale(locale); - } - translation_server->load_translations(); - ResourceLoader::load_translation_remaps(); //load remaps for resources - - ResourceLoader::load_path_remaps(); - audio_server->load_default_bus_layout(); if (use_debug_profiler && EngineDebugger::is_active()) { @@ -2454,6 +2445,7 @@ bool Main::iteration() { for (int iters = 0; iters < advance.physics_steps; ++iters) { uint64_t physics_begin = OS::get_singleton()->get_ticks_usec(); + PhysicsServer3D::get_singleton()->sync(); PhysicsServer3D::get_singleton()->flush_queries(); PhysicsServer2D::get_singleton()->sync(); @@ -2468,6 +2460,7 @@ bool Main::iteration() { message_queue->flush(); + PhysicsServer3D::get_singleton()->end_sync(); PhysicsServer3D::get_singleton()->step(physics_step * time_scale); PhysicsServer2D::get_singleton()->end_sync(); diff --git a/methods.py b/methods.py index 15eb82ae74..45cfe00959 100644 --- a/methods.py +++ b/methods.py @@ -145,34 +145,86 @@ def parse_cg_file(fname, uniforms, sizes, conditionals): fs.close() -def detect_modules(at_path): - module_list = OrderedDict() # name : path +def detect_modules(search_path, recursive=False): + """Detects and collects a list of C++ modules at specified path - modules_glob = os.path.join(at_path, "*") - files = glob.glob(modules_glob) - files.sort() # so register_module_types does not change that often, and also plugins are registered in alphabetic order + `search_path` - a directory path containing modules. The path may point to + a single module, which may have other nested modules. A module must have + "register_types.h", "SCsub", "config.py" files created to be detected. - for x in files: - if not is_module(x): - continue - name = os.path.basename(x) - path = x.replace("\\", "/") # win32 - module_list[name] = path + `recursive` - if `True`, then all subdirectories are searched for modules as + specified by the `search_path`, otherwise collects all modules under the + `search_path` directory. If the `search_path` is a module, it is collected + in all cases. - return module_list + Returns an `OrderedDict` with module names as keys, and directory paths as + values. If a path is relative, then it is a built-in module. If a path is + absolute, then it is a custom module collected outside of the engine source. + """ + modules = OrderedDict() + + def add_module(path): + module_name = os.path.basename(path) + module_path = path.replace("\\", "/") # win32 + modules[module_name] = module_path + + def is_engine(path): + # Prevent recursively detecting modules in self and other + # Godot sources when using `custom_modules` build option. + version_path = os.path.join(path, "version.py") + if os.path.exists(version_path): + with open(version_path) as f: + if 'short_name = "godot"' in f.read(): + return True + return False + + def get_files(path): + files = glob.glob(os.path.join(path, "*")) + # Sort so that `register_module_types` does not change that often, + # and plugins are registered in alphabetic order as well. + files.sort() + return files + + if not recursive: + if is_module(search_path): + add_module(search_path) + for path in get_files(search_path): + if is_engine(path): + continue + if is_module(path): + add_module(path) + else: + to_search = [search_path] + while to_search: + path = to_search.pop() + if is_module(path): + add_module(path) + for child in get_files(path): + if not os.path.isdir(child): + continue + if is_engine(child): + continue + to_search.insert(0, child) + return modules def is_module(path): - return os.path.isdir(path) and os.path.exists(os.path.join(path, "SCsub")) + if not os.path.isdir(path): + return False + must_exist = ["register_types.h", "SCsub", "config.py"] + for f in must_exist: + if not os.path.exists(os.path.join(path, f)): + return False + return True -def write_modules(module_list): +def write_modules(modules): includes_cpp = "" preregister_cpp = "" register_cpp = "" unregister_cpp = "" - for name, path in module_list.items(): + for name, path in modules.items(): try: with open(os.path.join(path, "register_types.h")): includes_cpp += '#include "' + path + '/register_types.h"\n' @@ -230,8 +282,6 @@ def convert_custom_modules_path(path): raise ValueError(err_msg % "point to an existing directory.") if path == os.path.realpath("modules"): raise ValueError(err_msg % "be a directory other than built-in `modules` directory.") - if is_module(path): - raise ValueError(err_msg % "point to a directory with modules, not a single module.") return path diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index 53ad826730..c2cfd96da5 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -262,9 +262,7 @@ return; } Promise.all([ - deleteDB("/home/web_user/projects"), - deleteDB("/home/web_user/.config"), - deleteDB("/home/web_user/.cache"), + deleteDB("/home/web_user"), ]).then(function(results) { alert("Done."); }).catch(function (err) { @@ -286,6 +284,10 @@ tabs.forEach(function (elem) { if (elem.id == 'tab-' + name) { elem.style.display = 'block'; + if (name == 'editor' || name == 'game') { + const canvas = document.getElementById(name + '-canvas'); + canvas.focus(); + } } else { elem.style.display = 'none'; } @@ -326,7 +328,7 @@ function startEditor(zip) { const INDETERMINATE_STATUS_STEP_MS = 100; - const persistentPaths = ['/home/web_user/.config', '/home/web_user/.cache', '/home/web_user/projects']; + const persistentPaths = ['/home/web_user']; var editorCanvas = document.getElementById('editor-canvas'); var gameCanvas = document.getElementById('game-canvas'); @@ -493,11 +495,11 @@ engine.setUnloadAfterInit(false); // Don't want to reload when starting game. engine.init('godot.tools').then(function() { if (zip) { - engine.copyToFS("/home/web_user/preload.zip", zip); + engine.copyToFS("/tmp/preload.zip", zip); } try { // Avoid user creating project in the persistent root folder. - engine.copyToFS("/home/web_user/projects/keep", new Uint8Array()); + engine.copyToFS("/home/web_user/keep", new Uint8Array()); } catch(e) { // File exists } diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp index 66eb81d7f2..92882a1cc8 100644 --- a/modules/basis_universal/texture_basisu.cpp +++ b/modules/basis_universal/texture_basisu.cpp @@ -207,7 +207,6 @@ Vector<uint8_t> TextureBasisU::get_basisu_data() const { }; TextureBasisU::TextureBasisU() { - flags = FLAGS_DEFAULT; texture = RenderingServer::get_singleton()->texture_create(); }; diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h index 0a4783eaff..282a0dfc8a 100644 --- a/modules/basis_universal/texture_basisu.h +++ b/modules/basis_universal/texture_basisu.h @@ -47,7 +47,7 @@ class TextureBasisU : public Texture { RID texture; Size2 tex_size; - uint32_t flags; + uint32_t flags = FLAGS_DEFAULT; Vector<uint8_t> data; diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index d3f12f0115..379e971458 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -55,24 +55,24 @@ protected: struct bmp_header_s { struct bmp_file_header_s { - uint16_t bmp_signature; - uint32_t bmp_file_size; - uint32_t bmp_file_padding; - uint32_t bmp_file_offset; + uint16_t bmp_signature = 0; + uint32_t bmp_file_size = 0; + uint32_t bmp_file_padding = 0; + uint32_t bmp_file_offset = 0; } bmp_file_header; struct bmp_info_header_s { - uint32_t bmp_header_size; - uint32_t bmp_width; - uint32_t bmp_height; - uint16_t bmp_planes; - uint16_t bmp_bit_count; - uint32_t bmp_compression; - uint32_t bmp_size_image; - uint32_t bmp_pixels_per_meter_x; - uint32_t bmp_pixels_per_meter_y; - uint32_t bmp_colors_used; - uint32_t bmp_important_colors; + uint32_t bmp_header_size = 0; + uint32_t bmp_width = 0; + uint32_t bmp_height = 0; + uint16_t bmp_planes = 0; + uint16_t bmp_bit_count = 0; + uint32_t bmp_compression = 0; + uint32_t bmp_size_image = 0; + uint32_t bmp_pixels_per_meter_x = 0; + uint32_t bmp_pixels_per_meter_y = 0; + uint32_t bmp_colors_used = 0; + uint32_t bmp_important_colors = 0; } bmp_info_header; }; diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index a5fa678fec..7cf666c119 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -80,18 +80,18 @@ public: private: // These are used by function callEvent. Instead to create this each call I create if one time. Variant call_event_res[5]; - Variant *call_event_res_ptr[5]; + Variant *call_event_res_ptr[5] = {}; - btGhostObject *btGhost; + btGhostObject *btGhost = nullptr; Vector<OverlappingObjectData> overlappingObjects; bool monitorable = true; PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; bool spOv_gravityPoint = false; - real_t spOv_gravityPointDistanceScale = 0; - real_t spOv_gravityPointAttenuation = 1; + real_t spOv_gravityPointDistanceScale = 0.0; + real_t spOv_gravityPointAttenuation = 1.0; Vector3 spOv_gravityVec = Vector3(0, -1, 0); - real_t spOv_gravityMag = 10; + real_t spOv_gravityMag = 10.0; real_t spOv_linearDump = 0.1; real_t spOv_angularDump = 0.1; int spOv_priority = 0; diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp index 1568cca63d..109854c9dd 100644 --- a/modules/bullet/btRayShape.cpp +++ b/modules/bullet/btRayShape.cpp @@ -39,11 +39,9 @@ */ btRayShape::btRayShape(btScalar length) : - btConvexInternalShape(), - m_shapeAxis(0, 0, 1) { + btConvexInternalShape() { m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE; setLength(length); - slipsOnSlope = false; } btRayShape::~btRayShape() { diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h index dcc4cc79c7..330755aa31 100644 --- a/modules/bullet/btRayShape.h +++ b/modules/bullet/btRayShape.h @@ -42,10 +42,10 @@ /// Ray shape around z axis ATTRIBUTE_ALIGNED16(class) btRayShape : public btConvexInternalShape { - btScalar m_length; - bool slipsOnSlope; + btScalar m_length = 0; + bool slipsOnSlope = false; /// The default axis is the z - btVector3 m_shapeAxis; + btVector3 m_shapeAxis = btVector3(0, 0, 1); btTransform m_cacheSupportPoint; btScalar m_cacheScaledLength; diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 9144a781a0..26e9f5a044 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -1059,16 +1059,16 @@ real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) { return body->get_linear_stiffness(); } -void BulletPhysicsServer3D::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) { +void BulletPhysicsServer3D::soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - body->set_areaAngular_stiffness(p_stiffness); + body->set_angular_stiffness(p_stiffness); } -real_t BulletPhysicsServer3D::soft_body_get_areaAngular_stiffness(RID p_body) { +real_t BulletPhysicsServer3D::soft_body_get_angular_stiffness(RID p_body) { SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); - return body->get_areaAngular_stiffness(); + return body->get_angular_stiffness(); } void BulletPhysicsServer3D::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) { diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index f2740c9c75..97b719ae8e 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -298,8 +298,8 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override; virtual real_t soft_body_get_linear_stiffness(RID p_body) override; - virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override; - virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override; + virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override; + virtual real_t soft_body_get_angular_stiffness(RID p_body) override; virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override; virtual real_t soft_body_get_volume_stiffness(RID p_body) override; diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index bea28f2183..c8081a53f1 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -110,7 +110,7 @@ public: }; protected: - Type type; + Type type = TYPE_AREA; ObjectID instance_id; uint32_t collisionLayer = 0; uint32_t collisionMask = 0; diff --git a/modules/bullet/config.py b/modules/bullet/config.py index d22f9454ed..be7cf74f6f 100644 --- a/modules/bullet/config.py +++ b/modules/bullet/config.py @@ -1,5 +1,6 @@ def can_build(env, platform): - return True + # API Changed and bullet is disabled at the moment + return False def configure(env): diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h index 0669d2739a..ca17349130 100644 --- a/modules/bullet/godot_motion_state.h +++ b/modules/bullet/godot_motion_state.h @@ -51,7 +51,7 @@ class GodotMotionState : public btMotionState { /// This data is used to store last world position btTransform bodyCurrentWorldTransform; - RigidBodyBullet *owner; + RigidBodyBullet *owner = nullptr; public: GodotMotionState(RigidBodyBullet *p_owner) : diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h index f705edef81..25798aecb4 100644 --- a/modules/bullet/godot_ray_world_algorithm.h +++ b/modules/bullet/godot_ray_world_algorithm.h @@ -45,7 +45,7 @@ class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm { const btDiscreteDynamicsWorld *m_world; btPersistentManifold *m_manifoldPtr; bool m_ownManifold = false; - bool m_isSwapped; + bool m_isSwapped = false; public: GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *world, btPersistentManifold *mf, const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped); diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index 4f40f7ecfd..f92665f3e4 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -59,8 +59,8 @@ struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResult bool m_pickRay = false; int m_shapeId = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; public: GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : @@ -84,8 +84,8 @@ public: // store all colliding object struct GodotAllConvexResultCallback : public btCollisionWorld::ConvexResultCallback { public: - PhysicsDirectSpaceState3D::ShapeResult *m_results; - int m_resultMax; + PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr; + int m_resultMax = 0; const Set<RID> *m_exclude; int count = 0; @@ -117,8 +117,8 @@ public: const Set<RID> *m_exclude; int m_shapeId = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), @@ -134,13 +134,13 @@ public: struct GodotAllContactResultCallback : public btCollisionWorld::ContactResultCallback { public: const btCollisionObject *m_self_object; - PhysicsDirectSpaceState3D::ShapeResult *m_results; - int m_resultMax; + PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr; + int m_resultMax = 0; const Set<RID> *m_exclude; int m_count = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), @@ -159,13 +159,13 @@ public: struct GodotContactPairContactResultCallback : public btCollisionWorld::ContactResultCallback { public: const btCollisionObject *m_self_object; - Vector3 *m_results; - int m_resultMax; + Vector3 *m_results = nullptr; + int m_resultMax = 0; const Set<RID> *m_exclude; int m_count = 0; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), @@ -183,14 +183,14 @@ public: struct GodotRestInfoContactResultCallback : public btCollisionWorld::ContactResultCallback { public: const btCollisionObject *m_self_object; - PhysicsDirectSpaceState3D::ShapeRestInfo *m_result; + PhysicsDirectSpaceState3D::ShapeRestInfo *m_result = nullptr; const Set<RID> *m_exclude; bool m_collided = false; - real_t m_min_distance = 0; - const btCollisionObject *m_rest_info_collision_object; + real_t m_min_distance = 0.0; + const btCollisionObject *m_rest_info_collision_object = nullptr; btVector3 m_rest_info_bt_point; - bool collide_with_bodies; - bool collide_with_areas; + bool collide_with_bodies = false; + bool collide_with_areas = false; GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeRestInfo *p_result, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) : m_self_object(p_self_object), diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h index 0b74a0cc4d..face6b4861 100644 --- a/modules/bullet/rid_bullet.h +++ b/modules/bullet/rid_bullet.h @@ -41,7 +41,7 @@ class BulletPhysicsServer3D; class RIDBullet { RID self; - BulletPhysicsServer3D *physicsServer; + BulletPhysicsServer3D *physicsServer = nullptr; public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 57b80cf50c..a4be7f9e07 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -81,8 +81,8 @@ public: } public: - RigidBodyBullet *body; - real_t deltaTime; + RigidBodyBullet *body = nullptr; + real_t deltaTime = 0.0; private: BulletPhysicsDirectBodyState3D() {} @@ -144,13 +144,13 @@ public: class RigidBodyBullet : public RigidCollisionObjectBullet { public: struct CollisionData { - RigidBodyBullet *otherObject; - int other_object_shape; - int local_shape; + RigidBodyBullet *otherObject = nullptr; + int other_object_shape = 0; + int local_shape = 0; Vector3 hitLocalLocation; Vector3 hitWorldLocation; Vector3 hitNormal; - real_t appliedImpulse; + real_t appliedImpulse = 0.0; }; struct ForceIntegrationCallback { @@ -169,7 +169,7 @@ public: }; struct KinematicUtilities { - RigidBodyBullet *owner; + RigidBodyBullet *owner = nullptr; btScalar safe_margin; Vector<KinematicShape> shapes; @@ -194,10 +194,10 @@ private: GodotMotionState *godotMotionState; btRigidBody *btBody; uint16_t locked_axis = 0; - real_t mass = 1; - real_t gravity_scale = 1; - real_t linearDamp = 0; - real_t angularDamp = 0; + real_t mass = 1.0; + real_t gravity_scale = 1.0; + real_t linearDamp = 0.0; + real_t angularDamp = 0.0; bool can_sleep = true; bool omit_forces_integration = false; bool can_integrate_forces = false; diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 63475822de..bfd95747eb 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -213,10 +213,10 @@ private: class HeightMapShapeBullet : public ShapeBullet { public: Vector<real_t> heights; - int width; - int depth; - real_t min_height; - real_t max_height; + int width = 0; + int depth = 0; + real_t min_height = 0.0; + real_t max_height = 0.0; HeightMapShapeBullet(); @@ -231,7 +231,7 @@ private: class RayShapeBullet : public ShapeBullet { public: - real_t length = 1; + real_t length = 1.0; bool slips_on_slope = false; RayShapeBullet(); diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index a490179964..91a1934e07 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -259,10 +259,10 @@ void SoftBodyBullet::set_linear_stiffness(real_t p_val) { } } -void SoftBodyBullet::set_areaAngular_stiffness(real_t p_val) { - areaAngular_stiffness = p_val; +void SoftBodyBullet::set_angular_stiffness(real_t p_val) { + angular_stiffness = p_val; if (bt_soft_body) { - mat0->m_kAST = areaAngular_stiffness; + mat0->m_kAST = angular_stiffness; } } @@ -409,7 +409,7 @@ void SoftBodyBullet::setup_soft_body() { bt_soft_body->generateBendingConstraints(2, mat0); mat0->m_kLST = linear_stiffness; - mat0->m_kAST = areaAngular_stiffness; + mat0->m_kAST = angular_stiffness; mat0->m_kVST = volume_stiffness; // Clusters allow to have Soft vs Soft collision but doesn't work well right now diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index b15b72daf9..23f6fba9a6 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -59,7 +59,7 @@ class SoftBodyBullet : public CollisionObjectBullet { private: btSoftBody *bt_soft_body = nullptr; Vector<Vector<int>> indices_table; - btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody + btSoftBody::Material *mat0 = nullptr; // This is just a copy of pointer managed by btSoftBody bool isScratched = false; Ref<Mesh> soft_mesh; @@ -67,7 +67,7 @@ private: int simulation_precision = 5; real_t total_mass = 1.; real_t linear_stiffness = 0.5; // [0,1] - real_t areaAngular_stiffness = 0.5; // [0,1] + real_t angular_stiffness = 0.5; // [0,1] real_t volume_stiffness = 0.5; // [0,1] real_t pressure_coefficient = 0.; // [-inf,+inf] real_t pose_matching_coefficient = 0.; // [0,1] @@ -129,8 +129,8 @@ public: void set_linear_stiffness(real_t p_val); _FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; } - void set_areaAngular_stiffness(real_t p_val); - _FORCE_INLINE_ real_t get_areaAngular_stiffness() const { return areaAngular_stiffness; } + void set_angular_stiffness(real_t p_val); + _FORCE_INLINE_ real_t get_angular_stiffness() const { return angular_stiffness; } void set_volume_stiffness(real_t p_val); _FORCE_INLINE_ real_t get_volume_stiffness() const { return volume_stiffness; } diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 79a5fdb3d2..7d337bc4d0 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -1092,13 +1092,13 @@ private: btDbvtVolume bounds; const btCollisionObject *self_collision_object; - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 0; + uint32_t collision_mask = 0; struct CompoundLeafCallback : btDbvt::ICollide { private: - RecoverPenetrationBroadPhaseCallback *parent_callback; - btCollisionObject *collision_object; + RecoverPenetrationBroadPhaseCallback *parent_callback = nullptr; + btCollisionObject *collision_object = nullptr; public: CompoundLeafCallback(RecoverPenetrationBroadPhaseCallback *p_parent_callback, btCollisionObject *p_collision_object) : @@ -1116,8 +1116,8 @@ private: public: struct BroadphaseResult { - btCollisionObject *collision_object; - int compound_child_index; + btCollisionObject *collision_object = nullptr; + int compound_child_index = 0; }; Vector<BroadphaseResult> results; diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 1caa3c2a0c..87aa2b9e93 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -100,12 +100,12 @@ class SpaceBullet : public RIDBullet { btGhostPairCallback *ghostPairCallback = nullptr; GodotFilterCallback *godotFilterCallback = nullptr; - btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver; - btVoronoiSimplexSolver *gjk_simplex_solver; + btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver = nullptr; + btVoronoiSimplexSolver *gjk_simplex_solver = nullptr; BulletPhysicsDirectSpaceState *direct_access; Vector3 gravityDirection = Vector3(0, -1, 0); - real_t gravityMagnitude = 10; + real_t gravityMagnitude = 10.0; real_t linear_damp = 0.0; real_t angular_damp = 0.0; diff --git a/modules/csg/csg.h b/modules/csg/csg.h index 1612c16a32..3fbed66e5c 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -48,9 +48,9 @@ struct CSGBrush { Vector3 vertices[3]; Vector2 uvs[3]; AABB aabb; - bool smooth; - bool invert; - int material; + bool smooth = false; + bool invert = false; + int material = 0; }; Vector<Face> faces; @@ -74,20 +74,20 @@ struct CSGBrushOperation { struct MeshMerge { struct Face { - bool from_b; - bool inside; - int points[3]; + bool from_b = false; + bool inside = false; + int points[3] = {}; Vector2 uvs[3]; - bool smooth; - bool invert; - int material_idx; + bool smooth = false; + bool invert = false; + int material_idx = 0; }; struct FaceBVH { - int face; - int left; - int right; - int next; + int face = 0; + int left = 0; + int right = 0; + int next = 0; Vector3 center; AABB aabb; }; @@ -142,7 +142,7 @@ struct CSGBrushOperation { Map<Ref<Material>, int> materials; Map<Vector3, int> vertex_map; OAHashMap<VertexKey, int, VertexKeyHash> snap_cache; - float vertex_snap; + float vertex_snap = 0.0; inline void _add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const; inline bool _bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const; @@ -159,7 +159,7 @@ struct CSGBrushOperation { }; struct Face2D { - int vertex_idx[3]; + int vertex_idx[3] = {}; }; Vector<Vertex2D> vertices; @@ -167,7 +167,7 @@ struct CSGBrushOperation { Plane plane; Transform to_2D; Transform to_3D; - float vertex_snap2; + float vertex_snap2 = 0.0; inline int _get_point_idx(const Vector2 &p_point); inline int _add_vertex(const Vertex2D &p_vertex); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 042c3aaca7..40ba457e43 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -45,7 +45,8 @@ void CSGShape3D::set_use_collision(bool p_enable) { if (use_collision) { root_collision_shape.instance(); - root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + root_collision_instance = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid()); PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space()); @@ -58,7 +59,7 @@ void CSGShape3D::set_use_collision(bool p_enable) { root_collision_instance = RID(); root_collision_shape.unref(); } - _change_notify(); + notify_property_list_changed(); } bool CSGShape3D::is_using_collision() const { @@ -494,7 +495,8 @@ void CSGShape3D::_notification(int p_what) { if (use_collision && is_root_shape()) { root_collision_shape.instance(); - root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + root_collision_instance = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform()); PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid()); PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space()); @@ -625,15 +627,6 @@ void CSGShape3D::_bind_methods() { } CSGShape3D::CSGShape3D() { - operation = OPERATION_UNION; - parent = nullptr; - brush = nullptr; - dirty = false; - snap = 0.001; - use_collision = false; - collision_layer = 1; - collision_mask = 1; - calculate_tangents = true; set_notify_local_transform(true); } @@ -927,25 +920,27 @@ CSGBrush *CSGSphere3D::_build_brush() { bool *invertw = invert.ptrw(); int face = 0; + const double lat_step = Math_TAU / rings; + const double lon_step = Math_TAU / radial_segments; for (int i = 1; i <= rings; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / rings); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double u0 = double(i - 1) / rings; - double lat1 = Math_PI * (-0.5 + (double)i / rings); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); double u1 = double(i) / rings; for (int j = radial_segments; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / radial_segments; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double v0 = double(i - 1) / radial_segments; - double lng1 = 2 * Math_PI * (double)(j) / radial_segments; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); double v1 = double(i) / radial_segments; @@ -1038,7 +1033,6 @@ void CSGSphere3D::set_radius(const float p_radius) { radius = p_radius; _make_dirty(); update_gizmo(); - _change_notify("radius"); } float CSGSphere3D::get_radius() const { @@ -1208,7 +1202,6 @@ void CSGBox3D::set_size(const Vector3 &p_size) { size = p_size; _make_dirty(); update_gizmo(); - _change_notify("size"); } Vector3 CSGBox3D::get_size() const { @@ -1266,8 +1259,8 @@ CSGBrush *CSGCylinder3D::_build_brush() { float inc = float(i) / sides; float inc_n = float((i + 1)) / sides; - float ang = inc * Math_PI * 2.0; - float ang_n = inc_n * Math_PI * 2.0; + float ang = inc * Math_TAU; + float ang_n = inc_n * Math_TAU; Vector3 base(Math::cos(ang), 0, Math::sin(ang)); Vector3 base_n(Math::cos(ang_n), 0, Math::sin(ang_n)); @@ -1390,7 +1383,6 @@ void CSGCylinder3D::set_radius(const float p_radius) { radius = p_radius; _make_dirty(); update_gizmo(); - _change_notify("radius"); } float CSGCylinder3D::get_radius() const { @@ -1401,7 +1393,6 @@ void CSGCylinder3D::set_height(const float p_height) { height = p_height; _make_dirty(); update_gizmo(); - _change_notify("height"); } float CSGCylinder3D::get_height() const { @@ -1508,8 +1499,8 @@ CSGBrush *CSGTorus3D::_build_brush() { float inci = float(i) / sides; float inci_n = float((i + 1)) / sides; - float angi = inci * Math_PI * 2.0; - float angi_n = inci_n * Math_PI * 2.0; + float angi = inci * Math_TAU; + float angi_n = inci_n * Math_TAU; Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi)); Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n)); @@ -1518,8 +1509,8 @@ CSGBrush *CSGTorus3D::_build_brush() { float incj = float(j) / ring_sides; float incj_n = float((j + 1)) / ring_sides; - float angj = incj * Math_PI * 2.0; - float angj_n = incj_n * Math_PI * 2.0; + float angj = incj * Math_TAU; + float angj_n = incj_n * Math_TAU; Vector2 normalj = Vector2(Math::cos(angj), Math::sin(angj)) * radius + Vector2(min_radius + radius, 0); Vector2 normalj_n = Vector2(Math::cos(angj_n), Math::sin(angj_n)) * radius + Vector2(min_radius + radius, 0); @@ -1611,7 +1602,6 @@ void CSGTorus3D::set_inner_radius(const float p_inner_radius) { inner_radius = p_inner_radius; _make_dirty(); update_gizmo(); - _change_notify("inner_radius"); } float CSGTorus3D::get_inner_radius() const { @@ -1622,7 +1612,6 @@ void CSGTorus3D::set_outer_radius(const float p_outer_radius) { outer_radius = p_outer_radius; _make_dirty(); update_gizmo(); - _change_notify("outer_radius"); } float CSGTorus3D::get_outer_radius() const { @@ -1891,8 +1880,8 @@ CSGBrush *CSGPolygon3D::_build_brush() { float inci = float(i) / spin_sides; float inci_n = float((i + 1)) / spin_sides; - float angi = -(inci * spin_degrees / 360.0) * Math_PI * 2.0; - float angi_n = -(inci_n * spin_degrees / 360.0) * Math_PI * 2.0; + float angi = -Math::deg2rad(inci * spin_degrees); + float angi_n = -Math::deg2rad(inci_n * spin_degrees); Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi)); Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n)); @@ -2269,7 +2258,7 @@ void CSGPolygon3D::set_mode(Mode p_mode) { mode = p_mode; _make_dirty(); update_gizmo(); - _change_notify(); + notify_property_list_changed(); } CSGPolygon3D::Mode CSGPolygon3D::get_mode() const { diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index 7dff8b6d3b..de7de09f00 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -50,23 +50,23 @@ public: }; private: - Operation operation; - CSGShape3D *parent; + Operation operation = OPERATION_UNION; + CSGShape3D *parent = nullptr; - CSGBrush *brush; + CSGBrush *brush = nullptr; AABB node_aabb; - bool dirty; - float snap; + bool dirty = false; + float snap = 0.001; - bool use_collision; - uint32_t collision_layer; - uint32_t collision_mask; + bool use_collision = false; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; Ref<ConcavePolygonShape3D> root_collision_shape; RID root_collision_instance; - bool calculate_tangents; + bool calculate_tangents = true; Ref<ArrayMesh> root_mesh; @@ -85,12 +85,12 @@ private: Vector<Vector2> uvs; Vector<float> tans; Ref<Material> material; - int last_added; + int last_added = 0; - Vector3 *verticesw; - Vector3 *normalsw; - Vector2 *uvsw; - float *tansw; + Vector3 *verticesw = nullptr; + Vector3 *normalsw = nullptr; + Vector2 *uvsw = nullptr; + float *tansw = nullptr; }; //mikktspace callbacks diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index 43faa52218..dbd6d9e9f9 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -37,26 +37,26 @@ #include <ConvectionKernels.h> struct CVTTCompressionJobParams { - bool is_hdr; - bool is_signed; - int bytes_per_pixel; + bool is_hdr = false; + bool is_signed = false; + int bytes_per_pixel = 0; cvtt::Options options; }; struct CVTTCompressionRowTask { const uint8_t *in_mm_bytes; - uint8_t *out_mm_bytes; - int y_start; - int width; - int height; + uint8_t *out_mm_bytes = nullptr; + int y_start = 0; + int width = 0; + int height = 0; }; struct CVTTCompressionJobQueue { CVTTCompressionJobParams job_params; const CVTTCompressionRowTask *job_tasks; - uint32_t num_tasks; - uint32_t current_task; + uint32_t num_tasks = 0; + uint32_t current_task = 0; }; static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const CVTTCompressionRowTask &p_row_task) { diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index 2865b3c9ae..2fef576b77 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -69,11 +69,11 @@ enum DDSFormat { struct DDSFormatInfo { const char *name; - bool compressed; - bool palette; - uint32_t divisor; - uint32_t block_size; - Image::Format format; + bool compressed = false; + bool palette = false; + uint32_t divisor = 0; + uint32_t block_size = 0; + Image::Format format = Image::Format::FORMAT_BPTC_RGBA; }; static const DDSFormatInfo dds_format_info[DDS_MAX] = { @@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 } }; -RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index 605e791969..cf93156423 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -36,7 +36,7 @@ class ResourceFormatDDS : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 66db9ab84e..91984b8928 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -866,28 +866,12 @@ void NetworkedMultiplayerENet::_bind_methods() { } NetworkedMultiplayerENet::NetworkedMultiplayerENet() { - active = false; - server = false; - refuse_connections = false; - server_relay = true; - unique_id = 0; - target_peer = 0; - current_packet.packet = nullptr; - transfer_mode = TRANSFER_MODE_RELIABLE; - channel_count = SYSCH_MAX; - transfer_channel = -1; - always_ordered = false; - connection_status = CONNECTION_DISCONNECTED; - compression_mode = COMPRESS_NONE; enet_compressor.context = this; enet_compressor.compress = enet_compress; enet_compressor.decompress = enet_decompress; enet_compressor.destroy = enet_compressor_destroy; bind_ip = IP_Address("*"); - - dtls_enabled = false; - dtls_verify = true; } NetworkedMultiplayerENet::~NetworkedMultiplayerENet() { diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 4baa48be5e..eb70d71c2c 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -62,35 +62,35 @@ private: SYSCH_MAX }; - bool active; - bool server; + bool active = false; + bool server = false; - uint32_t unique_id; + uint32_t unique_id = 0; - int target_peer; - TransferMode transfer_mode; - int transfer_channel; - int channel_count; - bool always_ordered; + int target_peer = 0; + TransferMode transfer_mode = TRANSFER_MODE_RELIABLE; + int transfer_channel = -1; + int channel_count = SYSCH_MAX; + bool always_ordered = false; ENetEvent event; - ENetPeer *peer; - ENetHost *host; + ENetPeer *peer = nullptr; + ENetHost *host = nullptr; - bool refuse_connections; - bool server_relay; + bool refuse_connections = false; + bool server_relay = true; - ConnectionStatus connection_status; + ConnectionStatus connection_status = CONNECTION_DISCONNECTED; Map<int, ENetPeer *> peer_map; struct Packet { - ENetPacket *packet; - int from; - int channel; + ENetPacket *packet = nullptr; + int from = 0; + int channel = 0; }; - CompressionMode compression_mode; + CompressionMode compression_mode = COMPRESS_NONE; List<Packet> incoming_packets; @@ -110,10 +110,10 @@ private: IP_Address bind_ip; - bool dtls_enabled; + bool dtls_enabled = false; Ref<CryptoKey> dtls_key; Ref<X509Certificate> dtls_cert; - bool dtls_verify; + bool dtls_verify = true; protected: static void _bind_methods(); diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index b0ea109f76..95db9315d5 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -35,14 +35,14 @@ struct ETC1Header { char tag[6]; // "PKM 10" - uint16_t format; // Format == number of mips (== zero) - uint16_t texWidth; // Texture dimensions, multiple of 4 (big-endian) - uint16_t texHeight; - uint16_t origWidth; // Original dimensions (big-endian) - uint16_t origHeight; + uint16_t format = 0; // Format == number of mips (== zero) + uint16_t texWidth = 0; // Texture dimensions, multiple of 4 (big-endian) + uint16_t texHeight = 0; + uint16_t origWidth = 0; // Original dimensions (big-endian) + uint16_t origHeight = 0; }; -RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h index 67fbee3a7e..2ed5e75807 100644 --- a/modules/etc/texture_loader_pkm.h +++ b/modules/etc/texture_loader_pkm.h @@ -36,7 +36,7 @@ class ResourceFormatPKM : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index e3a359e09a..86bd8b820d 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -110,6 +110,16 @@ bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const return false; } +void GDNativeLibrary::reset_state() { + config_file.instance(); + current_library_path = ""; + current_dependencies.clear(); + symbol_prefix = default_symbol_prefix; + load_once = default_load_once; + singleton = default_singleton; + reloadable = default_reloadable; +} + void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { // set entries List<String> entry_key_list; @@ -508,7 +518,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_ return result; } -RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<GDNativeLibrary> lib; lib.instance(); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 765087d176..a28c58ec0d 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -63,6 +63,8 @@ class GDNativeLibrary : public Resource { bool reloadable; public: + virtual void reset_state() override; + GDNativeLibrary(); ~GDNativeLibrary(); @@ -166,7 +168,7 @@ public: class GDNativeLibraryResourceLoader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 87a8c8e376..e68b60c5e6 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -47,6 +47,16 @@ void GDAPI godot_array_destroy(godot_array *p_self) { ((Array *)p_self)->~Array(); } +godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, godot_int p_index) { + Array *self = (Array *)p_self; + return (godot_variant *)&self->operator[](p_index); +} + +const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, godot_int p_index) { + const Array *self = (const Array *)p_self; + return (const godot_variant *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 86a6d6216c..df3e1255ac 100644 --- a/modules/gdnative/gdnative/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -42,6 +42,16 @@ void GDAPI godot_basis_new(godot_basis *p_self) { memnew_placement(p_self, Basis); } +godot_vector3 GDAPI *godot_basis_operator_index(godot_basis *p_self, godot_int p_index) { + Basis *self = (Basis *)p_self; + return (godot_vector3 *)&self->operator[](p_index); +} + +const godot_vector3 GDAPI *godot_basis_operator_index_const(const godot_basis *p_self, godot_int p_index) { + const Basis *self = (const Basis *)p_self; + return (const godot_vector3 *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp index 784c8d439e..12a800d333 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -42,6 +42,16 @@ void GDAPI godot_color_new(godot_color *p_self) { memnew_placement(p_self, Color); } +float GDAPI *godot_color_operator_index(godot_color *p_self, godot_int p_index) { + Color *self = (Color *)p_self; + return (float *)&self->operator[](p_index); +} + +const float GDAPI *godot_color_operator_index_const(const godot_color *p_self, godot_int p_index) { + const Color *self = (const Color *)p_self; + return (const float *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index d58e08f4b0..9fa4a27a83 100644 --- a/modules/gdnative/gdnative/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -31,6 +31,7 @@ #include "gdnative/dictionary.h" #include "core/variant/dictionary.h" +#include "core/variant/variant.h" static_assert(sizeof(godot_dictionary) == sizeof(Dictionary), "Dictionary size mismatch"); @@ -47,6 +48,16 @@ void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) { self->~Dictionary(); } +godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key) { + Dictionary *self = (Dictionary *)p_self; + return (godot_variant *)&self->operator[](*((const Variant *)p_key)); +} + +const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key) { + const Dictionary *self = (const Dictionary *)p_self; + return (const godot_variant *)&self->operator[](*((const Variant *)p_key)); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index c3d25f81c7..b84ce2d192 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -127,6 +127,17 @@ void GDAPI godot_free(void *p_ptr) { memfree(p_ptr); } +// Helper print functions. +void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { + _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR); +} +void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line) { + _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING); +} +void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line) { + _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT); +} + void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have) { String message = "Error loading GDNative file "; GDNativeLibrary *library = (GDNativeLibrary *)p_library; diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp index 9e4c6e6f38..63a2425b87 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -63,6 +63,16 @@ void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self) { ((PackedByteArray *)p_self)->~PackedByteArray(); } +uint8_t GDAPI *godot_packed_byte_array_operator_index(godot_packed_byte_array *p_self, godot_int p_index) { + PackedByteArray *self = (PackedByteArray *)p_self; + return (uint8_t *)&self->operator[](p_index); +} + +const uint8_t GDAPI *godot_packed_byte_array_operator_index_const(const godot_packed_byte_array *p_self, godot_int p_index) { + const PackedByteArray *self = (const PackedByteArray *)p_self; + return (const uint8_t *)&self->operator[](p_index); +} + // int32 void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *p_self) { @@ -73,6 +83,16 @@ void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self) { ((PackedInt32Array *)p_self)->~PackedInt32Array(); } +int32_t GDAPI *godot_packed_int32_array_operator_index(godot_packed_int32_array *p_self, godot_int p_index) { + PackedInt32Array *self = (PackedInt32Array *)p_self; + return (int32_t *)&self->operator[](p_index); +} + +const int32_t GDAPI *godot_packed_int32_array_operator_index_const(const godot_packed_int32_array *p_self, godot_int p_index) { + const PackedInt32Array *self = (const PackedInt32Array *)p_self; + return (const int32_t *)&self->operator[](p_index); +} + // int64 void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *p_self) { @@ -83,6 +103,16 @@ void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self) { ((PackedInt64Array *)p_self)->~PackedInt64Array(); } +int64_t GDAPI *godot_packed_int64_array_operator_index(godot_packed_int64_array *p_self, godot_int p_index) { + PackedInt64Array *self = (PackedInt64Array *)p_self; + return (int64_t *)&self->operator[](p_index); +} + +const int64_t GDAPI *godot_packed_int64_array_operator_index_const(const godot_packed_int64_array *p_self, godot_int p_index) { + const PackedInt64Array *self = (const PackedInt64Array *)p_self; + return (const int64_t *)&self->operator[](p_index); +} + // float32 void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *p_self) { @@ -93,6 +123,16 @@ void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self ((PackedFloat32Array *)p_self)->~PackedFloat32Array(); } +float GDAPI *godot_packed_float32_array_operator_index(godot_packed_float32_array *p_self, godot_int p_index) { + PackedFloat32Array *self = (PackedFloat32Array *)p_self; + return (float *)&self->operator[](p_index); +} + +const float GDAPI *godot_packed_float32_array_operator_index_const(const godot_packed_float32_array *p_self, godot_int p_index) { + const PackedFloat32Array *self = (const PackedFloat32Array *)p_self; + return (const float *)&self->operator[](p_index); +} + // float64 void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *p_self) { @@ -103,6 +143,16 @@ void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self ((PackedFloat64Array *)p_self)->~PackedFloat64Array(); } +double GDAPI *godot_packed_float64_array_operator_index(godot_packed_float64_array *p_self, godot_int p_index) { + PackedFloat64Array *self = (PackedFloat64Array *)p_self; + return (double *)&self->operator[](p_index); +} + +const double GDAPI *godot_packed_float64_array_operator_index_const(const godot_packed_float64_array *p_self, godot_int p_index) { + const PackedFloat64Array *self = (const PackedFloat64Array *)p_self; + return (const double *)&self->operator[](p_index); +} + // string void GDAPI godot_packed_string_array_new(godot_packed_string_array *p_self) { @@ -113,6 +163,16 @@ void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self) ((PackedStringArray *)p_self)->~PackedStringArray(); } +godot_string GDAPI *godot_packed_string_array_operator_index(godot_packed_string_array *p_self, godot_int p_index) { + PackedStringArray *self = (PackedStringArray *)p_self; + return (godot_string *)&self->operator[](p_index); +} + +const godot_string GDAPI *godot_packed_string_array_operator_index_const(const godot_packed_string_array *p_self, godot_int p_index) { + const PackedStringArray *self = (const PackedStringArray *)p_self; + return (const godot_string *)&self->operator[](p_index); +} + // vector2 void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *p_self) { @@ -123,6 +183,16 @@ void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self ((PackedVector2Array *)p_self)->~PackedVector2Array(); } +godot_vector2 GDAPI *godot_packed_vector2_array_operator_index(godot_packed_vector2_array *p_self, godot_int p_index) { + PackedVector2Array *self = (PackedVector2Array *)p_self; + return (godot_vector2 *)&self->operator[](p_index); +} + +const godot_vector2 GDAPI *godot_packed_vector2_array_operator_index_const(const godot_packed_vector2_array *p_self, godot_int p_index) { + const PackedVector2Array *self = (const PackedVector2Array *)p_self; + return (const godot_vector2 *)&self->operator[](p_index); +} + // vector2i void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *p_self) { @@ -133,6 +203,16 @@ void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_se ((Vector<Vector2i> *)p_self)->~Vector(); } +godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index(godot_packed_vector2i_array *p_self, godot_int p_index) { + Vector<Vector2i> *self = (Vector<Vector2i> *)p_self; + return (godot_vector2i *)&self->operator[](p_index); +} + +const godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index_const(const godot_packed_vector2i_array *p_self, godot_int p_index) { + const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self; + return (const godot_vector2i *)&self->operator[](p_index); +} + // vector3 void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *p_self) { @@ -143,6 +223,16 @@ void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self ((PackedVector3Array *)p_self)->~PackedVector3Array(); } +godot_vector3 GDAPI *godot_packed_vector3_array_operator_index(godot_packed_vector3_array *p_self, godot_int p_index) { + PackedVector3Array *self = (PackedVector3Array *)p_self; + return (godot_vector3 *)&self->operator[](p_index); +} + +const godot_vector3 GDAPI *godot_packed_vector3_array_operator_index_const(const godot_packed_vector3_array *p_self, godot_int p_index) { + const PackedVector3Array *self = (const PackedVector3Array *)p_self; + return (const godot_vector3 *)&self->operator[](p_index); +} + // vector3i void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self) { @@ -153,6 +243,16 @@ void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_se ((Vector<Vector3i> *)p_self)->~Vector(); } +godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index(godot_packed_vector3i_array *p_self, godot_int p_index) { + Vector<Vector3i> *self = (Vector<Vector3i> *)p_self; + return (godot_vector3i *)&self->operator[](p_index); +} + +const godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index_const(const godot_packed_vector3i_array *p_self, godot_int p_index) { + const Vector<Vector3i> *self = (const Vector<Vector3i> *)p_self; + return (const godot_vector3i *)&self->operator[](p_index); +} + // color void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self) { @@ -163,6 +263,16 @@ void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) { ((PackedColorArray *)p_self)->~PackedColorArray(); } +godot_color GDAPI *godot_packed_color_array_operator_index(godot_packed_color_array *p_self, godot_int p_index) { + PackedColorArray *self = (PackedColorArray *)p_self; + return (godot_color *)&self->operator[](p_index); +} + +const godot_color GDAPI *godot_packed_color_array_operator_index_const(const godot_packed_color_array *p_self, godot_int p_index) { + const PackedColorArray *self = (const PackedColorArray *)p_self; + return (const godot_color *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp index 87f1d7d8e5..836d6390d6 100644 --- a/modules/gdnative/gdnative/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -42,6 +42,16 @@ void GDAPI godot_quat_new(godot_quat *p_self) { memnew_placement(p_self, Quat); } +godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index) { + Quat *self = (Quat *)p_self; + return (godot_real_t *)&self->operator[](p_index); +} + +const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index) { + const Quat *self = (const Quat *)p_self; + return (const godot_real_t *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index e2c933f1ea..679174d5a5 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -42,6 +42,16 @@ void GDAPI godot_transform2d_new(godot_transform2d *p_self) { memnew_placement(p_self, Transform2D); } +godot_vector2 GDAPI *godot_transform2d_operator_index(godot_transform2d *p_self, godot_int p_index) { + Transform2D *self = (Transform2D *)p_self; + return (godot_vector2 *)&self->operator[](p_index); +} + +const godot_vector2 GDAPI *godot_transform2d_operator_index_const(const godot_transform2d *p_self, godot_int p_index) { + const Transform2D *self = (const Transform2D *)p_self; + return (const godot_vector2 *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 79f5a536e5..ee4353bb48 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -1065,6 +1065,22 @@ void GDAPI godot_variant_call_utility_function_with_cstring(const char *p_functi } } +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function(const godot_string_name *p_function) { + return (godot_ptr_utility_function)Variant::get_ptr_utility_function(*((const StringName *)p_function)); +} + +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function_with_cstring(const char *p_function) { + return (godot_ptr_utility_function)Variant::get_ptr_utility_function(StringName(p_function)); +} + +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function(const godot_string_name *p_function) { + return (godot_validated_utility_function)Variant::get_validated_utility_function(*((const StringName *)p_function)); +} + +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function_with_cstring(const char *p_function) { + return (godot_validated_utility_function)Variant::get_validated_utility_function(StringName(p_function)); +} + godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type(const godot_string_name *p_function) { return (godot_variant_utility_function_type)Variant::get_utility_function_type(*((const StringName *)p_function)); } diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index e2f957e4f2..ebb1996649 100644 --- a/modules/gdnative/gdnative/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -47,6 +47,26 @@ void GDAPI godot_vector2i_new(godot_vector2i *p_self) { memnew_placement(p_self, Vector2i); } +godot_real_t GDAPI *godot_vector2_operator_index(godot_vector2 *p_self, godot_int p_index) { + Vector2 *self = (Vector2 *)p_self; + return (godot_real_t *)&self->operator[](p_index); +} + +const godot_real_t GDAPI *godot_vector2_operator_index_const(const godot_vector2 *p_self, godot_int p_index) { + const Vector2 *self = (const Vector2 *)p_self; + return (const godot_real_t *)&self->operator[](p_index); +} + +int32_t GDAPI *godot_vector2i_operator_index(godot_vector2i *p_self, godot_int p_index) { + Vector2i *self = (Vector2i *)p_self; + return (int32_t *)&self->operator[](p_index); +} + +const int32_t GDAPI *godot_vector2i_operator_index_const(const godot_vector2i *p_self, godot_int p_index) { + const Vector2i *self = (const Vector2i *)p_self; + return (const int32_t *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index ee365edaec..0fe1b292a7 100644 --- a/modules/gdnative/gdnative/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -47,6 +47,26 @@ void GDAPI godot_vector3i_new(godot_vector3i *p_self) { memnew_placement(p_self, Vector3i); } +godot_real_t GDAPI *godot_vector3_operator_index(godot_vector3 *p_self, godot_int p_index) { + Vector3 *self = (Vector3 *)p_self; + return (godot_real_t *)&self->operator[](p_index); +} + +const godot_real_t GDAPI *godot_vector3_operator_index_const(const godot_vector3 *p_self, godot_int p_index) { + const Vector3 *self = (const Vector3 *)p_self; + return (const godot_real_t *)&self->operator[](p_index); +} + +int32_t GDAPI *godot_vector3i_operator_index(godot_vector3i *p_self, godot_int p_index) { + Vector3i *self = (Vector3i *)p_self; + return (int32_t *)&self->operator[](p_index); +} + +const int32_t GDAPI *godot_vector3i_operator_index_const(const godot_vector3i *p_self, godot_int p_index) { + const Vector3i *self = (const Vector3i *)p_self; + return (const int32_t *)&self->operator[](p_index); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 909e91393e..c163fbbc1b 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -153,6 +153,72 @@ ] }, { + "name": "godot_print_error", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_description" + ], + [ + "const char *", + "p_function" + ], + [ + "const char *", + "p_file" + ], + [ + "int", + "p_line" + ] + ] + }, + { + "name": "godot_print_warning", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_description" + ], + [ + "const char *", + "p_function" + ], + [ + "const char *", + "p_file" + ], + [ + "int", + "p_line" + ] + ] + }, + { + "name": "godot_print_script_error", + "return_type": "void", + "arguments": [ + [ + "const char *", + "p_description" + ], + [ + "const char *", + "p_function" + ], + [ + "const char *", + "p_file" + ], + [ + "int", + "p_line" + ] + ] + }, + { "name": "godot_get_class_tag", "return_type": "void *", "arguments": [ @@ -2371,6 +2437,46 @@ ] }, { + "name": "godot_variant_get_ptr_utility_function", + "return_type": "godot_ptr_utility_function", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_ptr_utility_function_with_cstring", + "return_type": "godot_ptr_utility_function", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_validated_utility_function", + "return_type": "godot_validated_utility_function", + "arguments": [ + [ + "const godot_string_name *", + "p_function" + ] + ] + }, + { + "name": "godot_variant_get_validated_utility_function_with_cstring", + "return_type": "godot_validated_utility_function", + "arguments": [ + [ + "const char *", + "p_function" + ] + ] + }, + { "name": "godot_variant_get_utility_function_type", "return_type": "godot_variant_utility_function_type", "arguments": [ @@ -2666,6 +2772,34 @@ ] }, { + "name": "godot_array_operator_index", + "return_type": "godot_variant *", + "arguments": [ + [ + "godot_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_array_operator_index_const", + "return_type": "const godot_variant *", + "arguments": [ + [ + "const godot_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_basis_new", "return_type": "void", "arguments": [ @@ -2676,6 +2810,34 @@ ] }, { + "name": "godot_basis_operator_index", + "return_type": "godot_vector3 *", + "arguments": [ + [ + "godot_basis *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_basis_operator_index_const", + "return_type": "const godot_vector3 *", + "arguments": [ + [ + "const godot_basis *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_callable_new", "return_type": "void", "arguments": [ @@ -2706,6 +2868,34 @@ ] }, { + "name": "godot_color_operator_index", + "return_type": "float *", + "arguments": [ + [ + "godot_color *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_color_operator_index_const", + "return_type": "const float *", + "arguments": [ + [ + "const godot_color *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_dictionary_new", "return_type": "void", "arguments": [ @@ -2726,6 +2916,34 @@ ] }, { + "name": "godot_dictionary_operator_index", + "return_type": "godot_variant *", + "arguments": [ + [ + "godot_dictionary *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ] + ] + }, + { + "name": "godot_dictionary_operator_index_const", + "return_type": "const godot_variant *", + "arguments": [ + [ + "const godot_dictionary *", + "p_self" + ], + [ + "const godot_variant *", + "p_key" + ] + ] + }, + { "name": "godot_node_path_new", "return_type": "void", "arguments": [ @@ -2766,6 +2984,34 @@ ] }, { + "name": "godot_packed_byte_array_operator_index", + "return_type": "uint8_t *", + "arguments": [ + [ + "godot_packed_byte_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_byte_array_operator_index_const", + "return_type": "const uint8_t *", + "arguments": [ + [ + "const godot_packed_byte_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_int32_array_new", "return_type": "void", "arguments": [ @@ -2786,6 +3032,34 @@ ] }, { + "name": "godot_packed_int32_array_operator_index", + "return_type": "int32_t *", + "arguments": [ + [ + "godot_packed_int32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_int32_array_operator_index_const", + "return_type": "const int32_t *", + "arguments": [ + [ + "const godot_packed_int32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_int64_array_new", "return_type": "void", "arguments": [ @@ -2806,6 +3080,34 @@ ] }, { + "name": "godot_packed_int64_array_operator_index", + "return_type": "int64_t *", + "arguments": [ + [ + "godot_packed_int64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_int64_array_operator_index_const", + "return_type": "const int64_t *", + "arguments": [ + [ + "const godot_packed_int64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_float32_array_new", "return_type": "void", "arguments": [ @@ -2826,6 +3128,34 @@ ] }, { + "name": "godot_packed_float32_array_operator_index", + "return_type": "float *", + "arguments": [ + [ + "godot_packed_float32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_float32_array_operator_index_const", + "return_type": "const float *", + "arguments": [ + [ + "const godot_packed_float32_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_float64_array_new", "return_type": "void", "arguments": [ @@ -2846,6 +3176,34 @@ ] }, { + "name": "godot_packed_float64_array_operator_index", + "return_type": "double *", + "arguments": [ + [ + "godot_packed_float64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_float64_array_operator_index_const", + "return_type": "const double *", + "arguments": [ + [ + "const godot_packed_float64_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_string_array_new", "return_type": "void", "arguments": [ @@ -2866,6 +3224,34 @@ ] }, { + "name": "godot_packed_string_array_operator_index", + "return_type": "godot_string *", + "arguments": [ + [ + "godot_packed_string_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_string_array_operator_index_const", + "return_type": "const godot_string *", + "arguments": [ + [ + "const godot_packed_string_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_vector2_array_new", "return_type": "void", "arguments": [ @@ -2886,6 +3272,34 @@ ] }, { + "name": "godot_packed_vector2_array_operator_index", + "return_type": "godot_vector2 *", + "arguments": [ + [ + "godot_packed_vector2_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector2_array_operator_index_const", + "return_type": "const godot_vector2 *", + "arguments": [ + [ + "const godot_packed_vector2_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_vector2i_array_new", "return_type": "void", "arguments": [ @@ -2906,6 +3320,34 @@ ] }, { + "name": "godot_packed_vector2i_array_operator_index", + "return_type": "godot_vector2i *", + "arguments": [ + [ + "godot_packed_vector2i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector2i_array_operator_index_const", + "return_type": "const godot_vector2i *", + "arguments": [ + [ + "const godot_packed_vector2i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_vector3_array_new", "return_type": "void", "arguments": [ @@ -2926,6 +3368,82 @@ ] }, { + "name": "godot_packed_vector3_array_operator_index", + "return_type": "godot_vector3 *", + "arguments": [ + [ + "godot_packed_vector3_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3_array_operator_index_const", + "return_type": "const godot_vector3 *", + "arguments": [ + [ + "const godot_packed_vector3_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_new", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector3i_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_destroy", + "return_type": "void", + "arguments": [ + [ + "godot_packed_vector3i_array *", + "p_self" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_operator_index", + "return_type": "godot_vector3i *", + "arguments": [ + [ + "godot_packed_vector3i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_vector3i_array_operator_index_const", + "return_type": "const godot_vector3i *", + "arguments": [ + [ + "const godot_packed_vector3i_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_packed_color_array_new", "return_type": "void", "arguments": [ @@ -2946,6 +3464,34 @@ ] }, { + "name": "godot_packed_color_array_operator_index", + "return_type": "godot_color *", + "arguments": [ + [ + "godot_packed_color_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_packed_color_array_operator_index_const", + "return_type": "const godot_color *", + "arguments": [ + [ + "const godot_packed_color_array *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_plane_new", "return_type": "void", "arguments": [ @@ -2966,6 +3512,34 @@ ] }, { + "name": "godot_quat_operator_index", + "return_type": "godot_real_t *", + "arguments": [ + [ + "godot_quat *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_quat_operator_index_const", + "return_type": "const godot_real_t *", + "arguments": [ + [ + "const godot_quat *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_rect2_new", "return_type": "void", "arguments": [ @@ -3278,6 +3852,34 @@ ] }, { + "name": "godot_transform2d_operator_index", + "return_type": "godot_vector2 *", + "arguments": [ + [ + "godot_transform2d *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_transform2d_operator_index_const", + "return_type": "const godot_vector2 *", + "arguments": [ + [ + "const godot_transform2d *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_vector2_new", "return_type": "void", "arguments": [ @@ -3288,6 +3890,34 @@ ] }, { + "name": "godot_vector2_operator_index", + "return_type": "godot_real_t *", + "arguments": [ + [ + "godot_vector2 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector2_operator_index_const", + "return_type": "const godot_real_t *", + "arguments": [ + [ + "const godot_vector2 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_vector2i_new", "return_type": "void", "arguments": [ @@ -3298,6 +3928,34 @@ ] }, { + "name": "godot_vector2i_operator_index", + "return_type": "int32_t *", + "arguments": [ + [ + "godot_vector2i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector2i_operator_index_const", + "return_type": "const int32_t *", + "arguments": [ + [ + "const godot_vector2i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_vector3_new", "return_type": "void", "arguments": [ @@ -3308,6 +3966,34 @@ ] }, { + "name": "godot_vector3_operator_index", + "return_type": "godot_real_t *", + "arguments": [ + [ + "godot_vector3 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector3_operator_index_const", + "return_type": "const godot_real_t *", + "arguments": [ + [ + "const godot_vector3 *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { "name": "godot_vector3i_new", "return_type": "void", "arguments": [ @@ -3316,6 +4002,34 @@ "r_dest" ] ] + }, + { + "name": "godot_vector3i_operator_index", + "return_type": "int32_t *", + "arguments": [ + [ + "godot_vector3i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] + }, + { + "name": "godot_vector3i_operator_index_const", + "return_type": "const int32_t *", + "arguments": [ + [ + "const godot_vector3i *", + "p_self" + ], + [ + "godot_int", + "p_index" + ] + ] } ] }, diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp index d3cca5b1be..dfb26c13e3 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.cpp +++ b/modules/gdnative/gdnative_library_editor_plugin.cpp @@ -257,7 +257,7 @@ void GDNativeLibraryEditor::_translate_to_config_file() { } } - library->_change_notify(); + library->notify_property_list_changed(); } } diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h index 184db3d817..61afb1aaaa 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.h +++ b/modules/gdnative/gdnative_library_editor_plugin.h @@ -95,9 +95,9 @@ public: class GDNativeLibraryEditorPlugin : public EditorPlugin { GDCLASS(GDNativeLibraryEditorPlugin, EditorPlugin); - GDNativeLibraryEditor *library_editor; - EditorNode *editor; - Button *button; + GDNativeLibraryEditor *library_editor = nullptr; + EditorNode *editor = nullptr; + Button *button = nullptr; public: virtual String get_name() const override { return "GDNativeLibrary"; } diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h index d734d49232..7603edaa73 100644 --- a/modules/gdnative/include/gdnative/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -47,9 +47,12 @@ typedef struct { #endif #include <gdnative/gdnative.h> +#include <gdnative/variant_struct.h> void GDAPI godot_array_new(godot_array *p_self); void GDAPI godot_array_destroy(godot_array *p_self); +godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, godot_int p_index); +const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h index d40ca3d6a5..af8d7cbdd3 100644 --- a/modules/gdnative/include/gdnative/basis.h +++ b/modules/gdnative/include/gdnative/basis.h @@ -49,6 +49,8 @@ typedef struct { #include <gdnative/gdnative.h> void GDAPI godot_basis_new(godot_basis *p_self); +godot_vector3 GDAPI *godot_basis_operator_index(godot_basis *p_self, godot_int p_index); +const godot_vector3 GDAPI *godot_basis_operator_index_const(const godot_basis *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h index 12c4a829bd..17a021e6ea 100644 --- a/modules/gdnative/include/gdnative/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -50,6 +50,8 @@ typedef struct { #include <gdnative/gdnative.h> void GDAPI godot_color_new(godot_color *p_self); +float GDAPI *godot_color_operator_index(godot_color *p_self, godot_int p_index); +const float GDAPI *godot_color_operator_index_const(const godot_color *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index 231d2ef578..d2afbc4c94 100644 --- a/modules/gdnative/include/gdnative/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -47,9 +47,12 @@ typedef struct { #endif #include <gdnative/gdnative.h> +#include <gdnative/variant_struct.h> void GDAPI godot_dictionary_new(godot_dictionary *p_self); void GDAPI godot_dictionary_destroy(godot_dictionary *p_self); +godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key); +const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 630966b035..a4ed7ebb8c 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -62,8 +62,6 @@ extern "C" { #include <stdbool.h> #include <stdint.h> -#define GODOT_API_VERSION 1 - ////// Error typedef enum { @@ -266,6 +264,11 @@ void GDAPI *godot_alloc(int p_bytes); void GDAPI *godot_realloc(void *p_ptr, int p_bytes); void GDAPI godot_free(void *p_ptr); +// Helper print functions. +void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line); +void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line); +void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line); + //tags used for safe dynamic casting void GDAPI *godot_get_class_tag(const godot_string_name *p_class); godot_object GDAPI *godot_object_cast_to(const godot_object *p_object, void *p_class_tag); diff --git a/modules/gdnative/include/gdnative/math_defs.h b/modules/gdnative/include/gdnative/math_defs.h index 05de157dd0..b5cf389506 100644 --- a/modules/gdnative/include/gdnative/math_defs.h +++ b/modules/gdnative/include/gdnative/math_defs.h @@ -35,6 +35,7 @@ extern "C" { #endif +#include <stdbool.h> #include <stdint.h> ////// bool diff --git a/modules/gdnative/include/gdnative/packed_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h index 1a26d8ed6d..621ed60cdf 100644 --- a/modules/gdnative/include/gdnative/packed_arrays.h +++ b/modules/gdnative/include/gdnative/packed_arrays.h @@ -164,54 +164,81 @@ typedef struct { void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *p_self); void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self); +uint8_t GDAPI *godot_packed_byte_array_operator_index(godot_packed_byte_array *p_self, godot_int p_index); +const uint8_t GDAPI *godot_packed_byte_array_operator_index_const(const godot_packed_byte_array *p_self, godot_int p_index); // Int32. void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *p_self); void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self); +int32_t GDAPI *godot_packed_int32_array_operator_index(godot_packed_int32_array *p_self, godot_int p_index); +const int32_t GDAPI *godot_packed_int32_array_operator_index_const(const godot_packed_int32_array *p_self, godot_int p_index); // Int64. void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *p_self); void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self); +int64_t GDAPI *godot_packed_int64_array_operator_index(godot_packed_int64_array *p_self, godot_int p_index); +const int64_t GDAPI *godot_packed_int64_array_operator_index_const(const godot_packed_int64_array *p_self, godot_int p_index); // Float32. void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *p_self); void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self); +float GDAPI *godot_packed_float32_array_operator_index(godot_packed_float32_array *p_self, godot_int p_index); +const float GDAPI *godot_packed_float32_array_operator_index_const(const godot_packed_float32_array *p_self, godot_int p_index); // Float64. void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *p_self); void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self); +double GDAPI *godot_packed_float64_array_operator_index(godot_packed_float64_array *p_self, godot_int p_index); +const double GDAPI *godot_packed_float64_array_operator_index_const(const godot_packed_float64_array *p_self, godot_int p_index); // String. void GDAPI godot_packed_string_array_new(godot_packed_string_array *p_self); void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self); +godot_string GDAPI *godot_packed_string_array_operator_index(godot_packed_string_array *p_self, godot_int p_index); +const godot_string GDAPI *godot_packed_string_array_operator_index_const(const godot_packed_string_array *p_self, godot_int p_index); // Vector2. void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *p_self); void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self); +godot_vector2 GDAPI *godot_packed_vector2_array_operator_index(godot_packed_vector2_array *p_self, godot_int p_index); +const godot_vector2 GDAPI *godot_packed_vector2_array_operator_index_const(const godot_packed_vector2_array *p_self, godot_int p_index); // Vector2i. void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *p_self); void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self); +godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index(godot_packed_vector2i_array *p_self, godot_int p_index); +const godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index_const(const godot_packed_vector2i_array *p_self, godot_int p_index); // Vector3. void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *p_self); void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self); +godot_vector3 GDAPI *godot_packed_vector3_array_operator_index(godot_packed_vector3_array *p_self, godot_int p_index); +const godot_vector3 GDAPI *godot_packed_vector3_array_operator_index_const(const godot_packed_vector3_array *p_self, godot_int p_index); + +// Vector3i. + +void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self); +void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_self); +godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index(godot_packed_vector3i_array *p_self, godot_int p_index); +const godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index_const(const godot_packed_vector3i_array *p_self, godot_int p_index); // Color. void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self); void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self); +godot_color GDAPI *godot_packed_color_array_operator_index(godot_packed_color_array *p_self, godot_int p_index); +const godot_color GDAPI *godot_packed_color_array_operator_index_const(const godot_packed_color_array *p_self, godot_int p_index); #ifdef __cplusplus } #endif -#endif // GODOT_POOL_ARRAYS_H +#endif // GODOT_PACKED_ARRAYS_H diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h index a87d0bdbe5..69bf427611 100644 --- a/modules/gdnative/include/gdnative/quat.h +++ b/modules/gdnative/include/gdnative/quat.h @@ -49,6 +49,8 @@ typedef struct { #include <gdnative/gdnative.h> void GDAPI godot_quat_new(godot_quat *p_self); +godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h index 85e3a86972..4a2bca7cfc 100644 --- a/modules/gdnative/include/gdnative/transform2d.h +++ b/modules/gdnative/include/gdnative/transform2d.h @@ -49,6 +49,8 @@ typedef struct { #include <gdnative/gdnative.h> void GDAPI godot_transform2d_new(godot_transform2d *p_self); +godot_vector2 GDAPI *godot_transform2d_operator_index(godot_transform2d *p_self, godot_int p_index); +const godot_vector2 GDAPI *godot_transform2d_operator_index_const(const godot_transform2d *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index 82bd030170..329a6faf51 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -36,15 +36,7 @@ extern "C" { #endif #include <gdnative/math_defs.h> - -#define GODOT_VARIANT_SIZE (sizeof(godot_real_t) * 4 + sizeof(int64_t)) - -#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_VARIANT_SIZE]; -} godot_variant; -#endif +#include <gdnative/variant_struct.h> typedef enum godot_variant_type { GODOT_VARIANT_TYPE_NIL, @@ -390,6 +382,10 @@ bool GDAPI godot_variant_has_utility_function(const godot_string_name *p_functio bool GDAPI godot_variant_has_utility_function_with_cstring(const char *p_function); void GDAPI godot_variant_call_utility_function(const godot_string_name *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error); void GDAPI godot_variant_call_utility_function_with_cstring(const char *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error); +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function(const godot_string_name *p_function); +godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function_with_cstring(const char *p_function); +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function(const godot_string_name *p_function); +godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function_with_cstring(const char *p_function); godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type(const godot_string_name *p_function); godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type_with_cstring(const char *p_function); int GDAPI godot_variant_get_utility_function_argument_count(const godot_string_name *p_function); diff --git a/modules/gdnative/include/gdnative/variant_struct.h b/modules/gdnative/include/gdnative/variant_struct.h new file mode 100644 index 0000000000..321c76c206 --- /dev/null +++ b/modules/gdnative/include/gdnative/variant_struct.h @@ -0,0 +1,53 @@ +/*************************************************************************/ +/* variant_struct.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_VARIANT_STRUCT_H +#define GODOT_VARIANT_STRUCT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <gdnative/math_defs.h> + +#define GODOT_VARIANT_SIZE (sizeof(godot_real_t) * 4 + sizeof(int64_t)) + +#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED +typedef struct { + uint8_t _dont_touch_that[GODOT_VARIANT_SIZE]; +} godot_variant; +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h index a21ab304d0..5ebb705ba4 100644 --- a/modules/gdnative/include/gdnative/vector2.h +++ b/modules/gdnative/include/gdnative/vector2.h @@ -59,6 +59,10 @@ typedef struct { void GDAPI godot_vector2_new(godot_vector2 *p_self); void GDAPI godot_vector2i_new(godot_vector2i *p_self); +godot_real_t GDAPI *godot_vector2_operator_index(godot_vector2 *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_vector2_operator_index_const(const godot_vector2 *p_self, godot_int p_index); +int32_t GDAPI *godot_vector2i_operator_index(godot_vector2i *p_self, godot_int p_index); +const int32_t GDAPI *godot_vector2i_operator_index_const(const godot_vector2i *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h index 354c7555b6..d37ebd3cc9 100644 --- a/modules/gdnative/include/gdnative/vector3.h +++ b/modules/gdnative/include/gdnative/vector3.h @@ -59,6 +59,10 @@ typedef struct { void GDAPI godot_vector3_new(godot_vector3 *p_self); void GDAPI godot_vector3i_new(godot_vector3i *p_self); +godot_real_t GDAPI *godot_vector3_operator_index(godot_vector3 *p_self, godot_int p_index); +const godot_real_t GDAPI *godot_vector3_operator_index_const(const godot_vector3 *p_self, godot_int p_index); +int32_t GDAPI *godot_vector3i_operator_index(godot_vector3i *p_self, godot_int p_index); +const int32_t GDAPI *godot_vector3i_operator_index_const(const godot_vector3i *p_self, godot_int p_index); #ifdef __cplusplus } diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 2b824938f2..3e75478cd8 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -122,6 +122,7 @@ struct ClassAPI { // @Unclear bool is_reference = false; bool has_indexing = false; // For builtin types. + String indexed_type; // For builtin types. bool is_keyed = false; // For builtin types. List<MethodAPI> methods; @@ -141,7 +142,7 @@ static String get_type_name(const PropertyInfo &info) { return info.class_name; } if (info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - return info.hint_string; + return info.class_name; } if (info.type == Variant::NIL && (info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) { return "Variant"; @@ -196,11 +197,32 @@ List<ClassAPI> generate_c_api_classes() { global_constants_api.singleton_name = "CoreConstants"; global_constants_api.is_instantiable = false; const int constants_count = CoreConstants::get_global_constant_count(); + + Map<StringName, EnumAPI> enum_api_map; for (int i = 0; i < constants_count; ++i) { - ConstantAPI constant_api; - constant_api.constant_name = CoreConstants::get_global_constant_name(i); - constant_api.constant_value = CoreConstants::get_global_constant_value(i); - global_constants_api.constants.push_back(constant_api); + StringName enum_name = CoreConstants::get_global_constant_enum(i); + String name = String(CoreConstants::get_global_constant_name(i)); + int value = CoreConstants::get_global_constant_value(i); + + if (enum_name == StringName()) { + ConstantAPI constant_api; + constant_api.constant_name = name; + constant_api.constant_value = value; + global_constants_api.constants.push_back(constant_api); + } else { + EnumAPI enum_api; + if (enum_api_map.has(enum_name)) { + enum_api = enum_api_map[enum_name]; + } else { + enum_api.name = String(enum_name); + } + enum_api.values.push_back(Pair(value, name)); + + enum_api_map[enum_name] = enum_api; + } + } + for (const Map<StringName, EnumAPI>::Element *E = enum_api_map.front(); E; E = E->next()) { + global_constants_api.enums.push_back(E->get()); } global_constants_api.constants.sort_custom<ConstantAPIComparator>(); api.push_back(global_constants_api); @@ -308,7 +330,9 @@ List<ClassAPI> generate_c_api_classes() { property_api.type = p->get().name.get_slice(":", 1); property_api.name = p->get().name.get_slice(":", 0); } else { - property_api.type = get_type_name(p->get()); + MethodInfo minfo; + ClassDB::get_method_info(class_name, property_api.getter, &minfo, true, false); + property_api.type = get_type_name(minfo.return_val); } property_api.index = ClassDB::get_property_index(class_name, p->get().name); @@ -370,7 +394,7 @@ List<ClassAPI> generate_c_api_classes() { arg_type = arg_info.name.get_slice(":", 1); arg_name = arg_info.name.get_slice(":", 0); } else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - arg_type = arg_info.hint_string; + arg_type = arg_info.class_name; } else if (arg_info.type == Variant::NIL) { arg_type = "Variant"; } else if (arg_info.type == Variant::OBJECT) { @@ -468,6 +492,7 @@ List<ClassAPI> generate_c_builtin_api_types() { class_api.class_name = Variant::get_type_name(type); class_api.is_instantiable = true; class_api.has_indexing = Variant::has_indexing(type); + class_api.indexed_type = Variant::get_type_name(Variant::get_indexed_element_type(type)); class_api.is_keyed = Variant::is_keyed(type); // Types that are passed by reference. switch (type) { @@ -768,6 +793,7 @@ static List<String> generate_c_builtin_api_json(const List<ClassAPI> &p_api) { append_indented(source, vformat(R"("is_instantiable": %s,)", class_api.is_instantiable ? "true" : "false")); append_indented(source, vformat(R"("is_reference": %s,)", class_api.is_reference ? "true" : "false")); append_indented(source, vformat(R"("has_indexing": %s,)", class_api.has_indexing ? "true" : "false")); + append_indented(source, vformat(R"("indexed_type": "%s",)", class_api.has_indexing && class_api.indexed_type == "Nil" ? "Variant" : class_api.indexed_type)); append_indented(source, vformat(R"("is_keyed": %s,)", class_api.is_keyed ? "true" : "false")); // Constructors. diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 19cf1f980b..5880c69763 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1196,13 +1196,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; -#ifndef NO_THREADS - has_objects_to_register = false; -#endif - -#ifdef DEBUG_ENABLED - profiling = false; -#endif _init_call_type = "nativescript_init"; _init_call_name = "nativescript_init"; @@ -1947,7 +1940,7 @@ void NativeReloadNode::_notification(int p_what) { #endif } -RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_no_cache) { return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 9d72bf39d1..81a158d09b 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -51,8 +51,8 @@ struct NativeScriptDesc { struct Method { godot_nativescript_instance_method method; MethodInfo info; - int rpc_mode; - uint16_t rpc_method_id; + int rpc_mode = 0; + uint16_t rpc_method_id = 0; String documentation; }; @@ -61,7 +61,7 @@ struct NativeScriptDesc { godot_nativescript_property_get_func getter; PropertyInfo info; Variant default_value; - int rset_mode; + int rset_mode = 0; uint16_t rset_property_id; String documentation; }; @@ -78,7 +78,7 @@ struct NativeScriptDesc { Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals StringName base; StringName base_native_type; - NativeScriptDesc *base_data; + NativeScriptDesc *base_data = nullptr; godot_nativescript_instance_create_func create_func; godot_nativescript_instance_destroy_func destroy_func; @@ -86,7 +86,7 @@ struct NativeScriptDesc { const void *type_tag = nullptr; - bool is_tool; + bool is_tool = false; inline NativeScriptDesc() { zeromem(&create_func, sizeof(godot_nativescript_instance_create_func)); @@ -254,7 +254,7 @@ class NativeScriptLanguage : public ScriptLanguage { private: static NativeScriptLanguage *singleton; - int lang_idx; + int lang_idx = 0; void _unload_stuff(bool p_reload = false); @@ -262,7 +262,7 @@ private: #ifndef NO_THREADS Set<Ref<GDNativeLibrary>> libs_to_init; Set<NativeScript *> scripts_to_register; - volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed + volatile bool has_objects_to_register = false; // so that we don't lock mutex every frame - it's rarely needed void defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script); #endif @@ -279,19 +279,19 @@ private: struct ProfileData { StringName signature; - uint64_t call_count; - uint64_t self_time; - uint64_t total_time; - uint64_t frame_call_count; - uint64_t frame_self_time; - uint64_t frame_total_time; - uint64_t last_frame_call_count; - uint64_t last_frame_self_time; - uint64_t last_frame_total_time; + uint64_t call_count = 0; + uint64_t self_time = 0; + uint64_t total_time = 0; + uint64_t frame_call_count = 0; + uint64_t frame_self_time = 0; + uint64_t frame_total_time = 0; + uint64_t last_frame_call_count = 0; + uint64_t last_frame_self_time = 0; + uint64_t last_frame_total_time = 0; }; Map<StringName, ProfileData> profile_data; - bool profiling; + bool profiling = false; public: // These two maps must only be touched on the main thread @@ -402,7 +402,7 @@ public: class ResourceFormatLoaderNativeScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index 865080fddf..536eb550e0 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -44,10 +44,10 @@ class PluginScriptInstance : public ScriptInstance { private: Ref<PluginScript> _script; - Object *_owner; + Object *_owner = nullptr; Variant _owner_variant; - godot_pluginscript_instance_data *_data; - const godot_pluginscript_instance_desc *_desc; + godot_pluginscript_instance_data *_data = nullptr; + const godot_pluginscript_instance_desc *_desc = nullptr; public: _FORCE_INLINE_ Object *get_owner() { return _owner; } diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp index cd1879a13e..f2165cd225 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.cpp +++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp @@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL _language = language; } -RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index 7b1a7f5423..e5d665c186 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -43,7 +43,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader { public: ResourceFormatLoaderPluginScript(PluginScriptLanguage *language); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/tests/test_variant.h b/modules/gdnative/tests/test_variant.h index 5284bf26f0..aeceb6e68f 100644 --- a/modules/gdnative/tests/test_variant.h +++ b/modules/gdnative/tests/test_variant.h @@ -124,6 +124,7 @@ TEST_CASE("[GDNative Variant] Variant evaluate") { godot_variant_new_int(&two, 2); godot_variant three; + godot_variant_new_nil(&three); bool valid = false; godot_variant_evaluate(GODOT_VARIANT_OP_ADD, &one, &two, &three, &valid); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 18d26a9528..a594ba41ec 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -360,7 +360,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) { /* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */ -RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index e64cda6602..140888cd4b 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -118,7 +118,7 @@ class VideoStreamPlaybackGDNative : public VideoStreamPlayback { AudioMixCallback mix_callback = nullptr; int num_channels = -1; - float time = 0; + float time = 0.0; bool seek_backward = false; int mix_rate = 0; double delay_compensation = 0; @@ -196,7 +196,7 @@ public: class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnavigation/nav_utils.h b/modules/gdnavigation/nav_utils.h index d1d1687a1f..d257a95ef1 100644 --- a/modules/gdnavigation/nav_utils.h +++ b/modules/gdnavigation/nav_utils.h @@ -51,7 +51,7 @@ union PointKey { int64_t z : 21; }; - uint64_t key; + uint64_t key = 0; bool operator<(const PointKey &p_key) const { return key < p_key.key; } }; @@ -86,8 +86,6 @@ struct Edge { /// The other `Polygon` at this edge id has this `Polygon`. int other_edge = -1; - - Edge() {} }; struct Polygon { @@ -111,8 +109,6 @@ struct Connection { int A_edge = -1; Polygon *B = nullptr; int B_edge = -1; - - Connection() {} }; struct NavigationPoly { @@ -141,12 +137,12 @@ struct NavigationPoly { }; struct FreeEdge { - bool is_free; - Polygon *poly; - uint32_t edge_id; + bool is_free = false; + Polygon *poly = nullptr; + uint32_t edge_id = 0; Vector3 edge_center; Vector3 edge_dir; - float edge_len_squared; + float edge_len_squared = 0.0; }; } // namespace gd diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h index d9e3345498..369cb1f9a3 100644 --- a/modules/gdnavigation/rvo_agent.h +++ b/modules/gdnavigation/rvo_agent.h @@ -53,7 +53,7 @@ class RvoAgent : public NavRid { NavMap *map = nullptr; RVO::Agent agent; AvoidanceComputedCallback callback; - uint32_t map_update_id; + uint32_t map_update_id = 0; public: RvoAgent(); diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp index 6e930b6bf4..9d0d91162c 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp @@ -44,7 +44,7 @@ Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Ve // Search strings in AssignmentNode -> text = "__", hint_tooltip = "__" etc. Error err; - RES loaded_res = ResourceLoader::load(p_path, "", false, &err); + RES loaded_res = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); if (err) { ERR_PRINT("Failed to load " + p_path); return err; diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index 5358a77140..fcf438422a 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -39,8 +39,8 @@ class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlugin { GDCLASS(GDScriptEditorTranslationParserPlugin, EditorTranslationParserPlugin); - Vector<String> *ids; - Vector<Vector<String>> *ids_ctx_plural; + Vector<String> *ids = nullptr; + Vector<Vector<String>> *ids_ctx_plural = nullptr; // List of patterns used for extracting translation strings. StringName tr_func = "tr"; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 502e294275..a129b73c1a 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -219,7 +219,7 @@ StringName GDScript::get_instance_base_type() const { } struct _GDScriptMemberSort { - int index; + int index = 0; StringName name; _FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; } }; @@ -1162,17 +1162,6 @@ String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript) GDScript::GDScript() : script_list(this) { - valid = false; - subclass_count = 0; - initializer = nullptr; - _base = nullptr; - _owner = nullptr; - tool = false; -#ifdef TOOLS_ENABLED - source_changed_cache = false; - placeholder_fallback_enabled = false; -#endif - #ifdef DEBUG_ENABLED { MutexLock lock(GDScriptLanguage::get_singleton()->lock); @@ -2327,7 +2316,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na /*************** RESOURCE ***************/ -RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 37f01b2571..12c909fd4f 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -57,11 +57,11 @@ public: class GDScript : public Script { GDCLASS(GDScript, Script); - bool tool; - bool valid; + bool tool = false; + bool valid = false; struct MemberInfo { - int index; + int index = 0; StringName setter; StringName getter; MultiplayerAPI::RPCMode rpc_mode; @@ -77,8 +77,8 @@ class GDScript : public Script { Ref<GDScriptNativeClass> native; Ref<GDScript> base; - GDScript *_base; //fast pointer access - GDScript *_owner; //for subclasses + GDScript *_base = nullptr; //fast pointer access + GDScript *_owner = nullptr; //for subclasses Set<StringName> members; //members are just indices to the instanced script. Map<StringName, Variant> constants; @@ -97,8 +97,8 @@ class GDScript : public Script { Map<StringName, Variant> member_default_values_cache; Ref<GDScript> base_cache; Set<ObjectID> inheriters_cache; - bool source_changed_cache; - bool placeholder_fallback_enabled; + bool source_changed_cache = false; + bool placeholder_fallback_enabled = false; void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); DocData::ClassDoc doc; @@ -121,7 +121,7 @@ class GDScript : public Script { GDScriptFunction *implicit_initializer = nullptr; GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate - int subclass_count; + int subclass_count = 0; Set<Object *> instances; //exported members String source; @@ -529,7 +529,7 @@ public: class ResourceFormatLoaderGDScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 00953ad752..651391f972 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -133,8 +133,8 @@ class GDScriptCompiler { Error _parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); Error _parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); void _make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); - int err_line; - int err_column; + int err_line = 0; + int err_column = 0; StringName source; String error; bool within_await = false; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 2171426e6f..c6c9a439df 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -77,14 +77,14 @@ int GDScriptFunction::get_max_stack_size() const { } struct _GDFKC { - int order; + int order = 0; List<int> pos; }; struct _GDFKCS { - int order; + int order = 0; StringName id; - int pos; + int pos = 0; bool operator<(const _GDFKCS &p_r) const { return order < p_r.order; @@ -294,7 +294,6 @@ void GDScriptFunctionState::_bind_methods() { GDScriptFunctionState::GDScriptFunctionState() : scripts_list(this), instances_list(this) { - function = nullptr; } GDScriptFunctionState::~GDScriptFunctionState() { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 6c791836b9..e64630a743 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -420,19 +420,19 @@ private: public: struct CallState { - GDScript *script; - GDScriptInstance *instance; + GDScript *script = nullptr; + GDScriptInstance *instance = nullptr; #ifdef DEBUG_ENABLED StringName function_name; String script_path; #endif Vector<uint8_t> stack; - int stack_size; + int stack_size = 0; Variant self; - uint32_t alloca_size; - int ip; - int line; - int defarg; + uint32_t alloca_size = 0; + int ip = 0; + int line = 0; + int defarg = 0; Variant result; }; @@ -488,7 +488,7 @@ public: class GDScriptFunctionState : public Reference { GDCLASS(GDScriptFunctionState, Reference); friend class GDScriptFunction; - GDScriptFunction *function; + GDScriptFunction *function = nullptr; GDScriptFunction::CallState state; Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Ref<GDScriptFunctionState> first_state; diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index f43708b81f..d59b68b602 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -351,7 +351,7 @@ public: OP_COMP_GREATER_EQUAL, }; - OpType operation; + OpType operation = OpType::OP_ADDITION; Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *left_operand = nullptr; ExpressionNode *right_operand = nullptr; @@ -753,7 +753,7 @@ public: struct MatchBranchNode : public Node { Vector<PatternNode *> patterns; - SuiteNode *block; + SuiteNode *block = nullptr; bool has_wildcard = false; MatchBranchNode() { @@ -1001,7 +1001,7 @@ public: OP_LOGIC_NOT, }; - OpType operation; + OpType operation = OP_POSITIVE; Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *operand = nullptr; diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index cdb0072294..bea4b14019 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -178,7 +178,6 @@ public: } Token() { - type = EMPTY; } }; diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp index 12ed56a568..98ada9de4d 100644 --- a/modules/gdscript/language_server/gdscript_language_server.cpp +++ b/modules/gdscript/language_server/gdscript_language_server.cpp @@ -36,11 +36,6 @@ #include "editor/editor_node.h" GDScriptLanguageServer::GDScriptLanguageServer() { - thread_running = false; - started = false; - - use_thread = false; - port = 6008; _EDITOR_DEF("network/language_server/remote_port", port); _EDITOR_DEF("network/language_server/enable_smart_resolve", true); _EDITOR_DEF("network/language_server/show_native_symbols_in_editor", false); diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h index 7b7837a463..29c5ddd70e 100644 --- a/modules/gdscript/language_server/gdscript_language_server.h +++ b/modules/gdscript/language_server/gdscript_language_server.h @@ -41,10 +41,10 @@ class GDScriptLanguageServer : public EditorPlugin { GDScriptLanguageProtocol protocol; Thread thread; - bool thread_running; - bool started; - bool use_thread; - int port; + bool thread_running = false; + bool started = false; + bool use_thread = false; + int port = 6008; static void thread_main(void *p_userdata); private: diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 6a913edbbf..96744a15d7 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -547,7 +547,7 @@ struct TextDocumentItem { * The version number of this document (it will increase after each * change, including undo/redo). */ - int version; + int version = 0; /** * The content of the opened text document. @@ -584,7 +584,7 @@ struct TextDocumentContentChangeEvent { /** * The length of the range that got replaced. */ - int rangeLength; + int rangeLength = 0; /** * The new text of the range/document. @@ -656,12 +656,12 @@ struct Diagnostic { * The diagnostic's severity. Can be omitted. If omitted it is up to the * client to interpret diagnostics as error, warning, info or hint. */ - int severity; + int severity = 0; /** * The diagnostic's code, which might appear in the user interface. */ - int code; + int code = 0; /** * A human-readable string describing the source of this @@ -833,7 +833,7 @@ struct CompletionItem { * an icon is chosen by the editor. The standardized set * of available values is defined in `CompletionItemKind`. */ - int kind; + int kind = 0; /** * A human-readable string with additional information @@ -891,7 +891,7 @@ struct CompletionItem { * The format of the insert text. The format applies to both the `insertText` property * and the `newText` property of a provided `textEdit`. */ - int insertTextFormat; + int insertTextFormat = 0; /** * An edit which is applied to a document when selecting this completion. When an edit is provided the value of @@ -1003,7 +1003,7 @@ struct CompletionList { * This list it not complete. Further typing should result in recomputing * this list. */ - bool isIncomplete; + bool isIncomplete = false; /** * The completion items. diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/gltf_camera.h index e5c2041793..bf94b80bef 100644 --- a/modules/gltf/gltf_camera.h +++ b/modules/gltf/gltf_camera.h @@ -38,8 +38,8 @@ class GLTFCamera : public Resource { private: bool perspective = true; - float fov_size = 75; - float zfar = 4000; + float fov_size = 75.0; + float zfar = 4000.0; float znear = 0.05; protected: diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index cce0740121..4868347a74 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -2391,7 +2391,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { e["targetNames"] = target_names; for (int j = 0; j < target_names.size(); j++) { - real_t weight = 0; + real_t weight = 0.0; if (j < state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) { weight = state->meshes.write[gltf_mesh_i]->get_blend_weights()[j]; } @@ -5569,7 +5569,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, animation->set_loop(true); } - float length = 0; + float length = 0.0; for (Map<int, GLTFAnimation::Track>::Element *track_i = anim->get_tracks().front(); track_i; track_i = track_i->next()) { const GLTFAnimation::Track &track = track_i->get(); diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 4dccb03369..134aadb75e 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -8,6 +8,7 @@ GridMaps use a [MeshLibrary] which contains a list of tiles. Each tile is a mesh with materials plus optional collision and navigation shapes. A GridMap contains a collection of cells. Each grid cell refers to a tile in the [MeshLibrary]. All cells in the map have the same dimensions. Internally, a GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells. + [b]Note:[/b] GridMap doesn't extend [VisualInstance3D] and therefore can't be hidden or cull masked based on [member VisualInstance3D.layers]. If you make a light not affect the first layer, the whole GridMap won't be lit by the light in question. </description> <tutorials> <link title="Using gridmaps">https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 5a17541075..e7c252dc53 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -189,7 +189,6 @@ void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { } _recreate_octant_data(); - _change_notify("mesh_library"); } Ref<MeshLibrary> GridMap::get_mesh_library() const { @@ -286,7 +285,8 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) { //create octant because it does not exist Octant *g = memnew(Octant); g->dirty = true; - g->static_body = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + g->static_body = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(g->static_body, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id()); PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer); PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask); @@ -491,7 +491,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Octant::MultimeshInstance mmi; RID mm = RS::get_singleton()->multimesh_create(); - RS::get_singleton()->multimesh_allocate(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); + RS::get_singleton()->multimesh_allocate_data(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; @@ -700,8 +700,6 @@ void GridMap::_update_visibility() { return; } - _change_notify("visible"); - for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) { Octant *octant = e->value(); for (int i = 0; i < octant->multimesh_instances.size(); i++) { @@ -1046,26 +1044,7 @@ RID GridMap::get_bake_mesh_instance(int p_idx) { } GridMap::GridMap() { - collision_layer = 1; - collision_mask = 1; - - cell_size = Vector3(2, 2, 2); - octant_size = 8; - awaiting_update = false; - _in_tree = false; - center_x = true; - center_y = true; - center_z = true; - - clip = false; - clip_floor = 0; - clip_axis = Vector3::AXIS_Z; - clip_above = true; - cell_scale = 1.0; - - navigation = nullptr; set_notify_transform(true); - recreating_octants = false; } GridMap::~GridMap() { diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 48ad95f9ff..e5ec4bb602 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -53,7 +53,7 @@ class GridMap : public Node3D { int16_t y; int16_t z; }; - uint64_t key; + uint64_t key = 0; _FORCE_INLINE_ bool operator<(const IndexKey &p_key) const { return key < p_key.key; @@ -68,7 +68,7 @@ class GridMap : public Node3D { y = (int16_t)p_vector.y; z = (int16_t)p_vector.z; } - IndexKey() { key = 0; } + IndexKey() {} }; /** @@ -80,13 +80,7 @@ class GridMap : public Node3D { unsigned int rot : 5; unsigned int layer : 8; }; - uint32_t cell; - - Cell() { - item = 0; - rot = 0; - layer = 0; - } + uint32_t cell = 0; }; /** @@ -103,7 +97,7 @@ class GridMap : public Node3D { RID instance; RID multimesh; struct Item { - int index; + int index = 0; Transform transform; IndexKey key; }; @@ -116,7 +110,7 @@ class GridMap : public Node3D { RID collision_debug; RID collision_debug_instance; - bool dirty; + bool dirty = false; RID static_body; Map<IndexKey, NavMesh> navmesh_ids; }; @@ -129,35 +123,37 @@ class GridMap : public Node3D { int16_t empty; }; - uint64_t key; + uint64_t key = 0; _FORCE_INLINE_ bool operator<(const OctantKey &p_key) const { return key < p_key.key; } //OctantKey(const IndexKey& p_k, int p_item) { indexkey=p_k.key; item=p_item; } - OctantKey() { key = 0; } + OctantKey() {} }; - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; Transform last_transform; - bool _in_tree; - Vector3 cell_size; - int octant_size; - bool center_x, center_y, center_z; - float cell_scale; - Navigation3D *navigation; + bool _in_tree = false; + Vector3 cell_size = Vector3(2, 2, 2); + int octant_size = 8; + bool center_x = true; + bool center_y = true; + bool center_z = true; + float cell_scale = 1.0; + Navigation3D *navigation = nullptr; - bool clip; - bool clip_above; - int clip_floor; + bool clip = false; + bool clip_above = true; + int clip_floor = 0; - bool recreating_octants; + bool recreating_octants = false; - Vector3::Axis clip_axis; + Vector3::Axis clip_axis = Vector3::AXIS_Z; Ref<MeshLibrary> mesh_library; @@ -167,10 +163,10 @@ class GridMap : public Node3D { void _recreate_octant_data(); struct BakeLight { - RS::LightType type; + RS::LightType type = RS::LightType::LIGHT_DIRECTIONAL; Vector3 pos; Vector3 dir; - float param[RS::LIGHT_PARAM_MAX]; + float param[RS::LIGHT_PARAM_MAX] = {}; }; _FORCE_INLINE_ Vector3 _octant_get_offset(const OctantKey &p_key) const { @@ -183,7 +179,7 @@ class GridMap : public Node3D { bool _octant_update(const OctantKey &p_key); void _octant_clean_up(const OctantKey &p_key); void _octant_transform(const OctantKey &p_key); - bool awaiting_update; + bool awaiting_update = false; void _queue_octants_dirty(); void _update_octants_callback(); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 4732a3f62d..da9cdb9bc5 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -769,7 +769,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In struct _CGMEItemSort { String name; - int id; + int id = 0; _FORCE_INLINE_ bool operator<(const _CGMEItemSort &r_it) const { return name < r_it.name; } }; @@ -1151,7 +1151,6 @@ void GridMapEditor::_bind_methods() { } GridMapEditor::GridMapEditor(EditorNode *p_editor) { - input_action = INPUT_NONE; editor = p_editor; undo_redo = p_editor->get_undo_redo(); @@ -1173,7 +1172,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { floor->set_min(-32767); floor->set_max(32767); floor->set_step(1); - floor->get_line_edit()->add_theme_constant_override("minimum_spaces", 16); + floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 16); spatial_editor_hb->add_child(floor); floor->connect("value_changed", callable_mp(this, &GridMapEditor::_floor_changed)); @@ -1234,7 +1233,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { settings_pick_distance->set_value(EDITOR_DEF("editors/grid_map/pick_distance", 5000.0)); settings_vbc->add_margin_child(TTR("Pick Distance:"), settings_pick_distance); - clip_mode = CLIP_DISABLED; options->get_popup()->connect("id_pressed", callable_mp(this, &GridMapEditor::_menu_option)); HBoxContainer *hb = memnew(HBoxContainer); @@ -1275,8 +1273,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { EDITOR_DEF("editors/grid_map/preview_size", 64); - display_mode = DISPLAY_THUMBNAIL; - mesh_library_palette = memnew(ItemList); add_child(mesh_library_palette); mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL); @@ -1296,11 +1292,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { edit_floor[1] = -1; edit_floor[2] = -1; - cursor_visible = false; - selected_palette = -1; - lock_view = false; - cursor_rot = 0; - selection_mesh = RenderingServer::get_singleton()->mesh_create(); paste_mesh = RenderingServer::get_singleton()->mesh_create(); @@ -1418,8 +1409,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { } _set_selection(false); - updating = false; - accumulated_floor_delta = 0.0; indicator_mat.instance(); indicator_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 0c0ec64680..6c7f0bedf6 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -65,11 +65,11 @@ class GridMapEditor : public VBoxContainer { }; UndoRedo *undo_redo; - InputAction input_action; + InputAction input_action = INPUT_NONE; Panel *panel; MenuButton *options; SpinBox *floor; - double accumulated_floor_delta; + double accumulated_floor_delta = 0.0; Button *mode_thumbnail; Button *mode_list; LineEdit *search_box; @@ -82,19 +82,19 @@ class GridMapEditor : public VBoxContainer { struct SetItem { Vector3i position; - int new_value; - int new_orientation; - int old_value; - int old_orientation; + int new_value = 0; + int new_orientation = 0; + int old_value = 0; + int old_orientation = 0; }; List<SetItem> set_items; GridMap *node = nullptr; MeshLibrary *last_mesh_library; - ClipMode clip_mode; + ClipMode clip_mode = CLIP_DISABLED; - bool lock_view; + bool lock_view = false; Transform grid_xform; Transform edit_grid_xform; Vector3::Axis edit_axis; @@ -112,9 +112,9 @@ class GridMapEditor : public VBoxContainer { RID paste_instance; struct ClipboardItem { - int cell_item; + int cell_item = 0; Vector3 grid_offset; - int orientation; + int orientation = 0; RID instance; }; @@ -125,14 +125,14 @@ class GridMapEditor : public VBoxContainer { Ref<StandardMaterial3D> outer_mat; Ref<StandardMaterial3D> selection_floor_mat; - bool updating; + bool updating = false; struct Selection { Vector3 click; Vector3 current; Vector3 begin; Vector3 end; - bool active; + bool active = false; } selection; Selection last_selection; @@ -141,18 +141,18 @@ class GridMapEditor : public VBoxContainer { Vector3 current; Vector3 begin; Vector3 end; - int orientation; + int orientation = 0; }; PasteIndicator paste_indicator; - bool cursor_visible; + bool cursor_visible = false; Transform cursor_transform; Vector3 cursor_origin; - int display_mode; - int selected_palette; - int cursor_rot; + int display_mode = DISPLAY_THUMBNAIL; + int selected_palette = -1; + int cursor_rot = 0; enum Menu { MENU_OPTION_NEXT_LEVEL, diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index f31eb3f066..82aaa492fc 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -93,8 +93,8 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con l.direction[2] = p_direction.z; l.range = p_range; l.attenuation = p_attenuation; - l.spot_angle = Math::deg2rad(p_spot_angle); - l.spot_attenuation = p_spot_attenuation; + l.cos_spot_angle = Math::cos(Math::deg2rad(p_spot_angle)); + l.inv_spot_attenuation = 1.0f / p_spot_attenuation; l.color[0] = p_color.r; l.color[1] = p_color.g; l.color[2] = p_color.b; diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index bb735baf6c..f2a826a447 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -46,18 +46,18 @@ class LightmapperRD : public Lightmapper { }; struct Light { - float position[3]; + float position[3] = {}; uint32_t type = LIGHT_TYPE_DIRECTIONAL; - float direction[3]; - float energy; - float color[3]; - float size; - float range; - float attenuation; - float spot_angle; - float spot_attenuation; - uint32_t static_bake; - uint32_t pad[3]; + float direction[3] = {}; + float energy = 0.0; + float color[3] = {}; + float size = 0.0; + float range = 0.0; + float attenuation = 0.0; + float cos_spot_angle = 0.0; + float inv_spot_attenuation = 0.0; + uint32_t static_bake = 0; + uint32_t pad[3] = {}; bool operator<(const Light &p_light) const { return type < p_light.type; @@ -65,10 +65,10 @@ class LightmapperRD : public Lightmapper { }; struct Vertex { - float position[3]; - float normal_z; - float uv[2]; - float normal_xy[2]; + float position[3] = {}; + float normal_z = 0.0; + float uv[2] = {}; + float normal_xy[2] = {}; bool operator==(const Vertex &p_vtx) const { return (position[0] == p_vtx.position[0]) && @@ -102,7 +102,7 @@ class LightmapperRD : public Lightmapper { }; struct Probe { - float position[4]; + float position[4] = {}; }; Vector<Probe> probe_positions; @@ -158,15 +158,15 @@ class LightmapperRD : public Lightmapper { }; struct Box { - float min_bounds[3]; - float pad0; - float max_bounds[3]; - float pad1; + float min_bounds[3] = {}; + float pad0 = 0.0; + float max_bounds[3] = {}; + float pad1 = 0.0; }; struct Triangle { - uint32_t indices[3]; - uint32_t slice; + uint32_t indices[3] = {}; + uint32_t slice = 0; bool operator<(const Triangle &p_triangle) const { return slice < p_triangle.slice; } @@ -177,8 +177,8 @@ class LightmapperRD : public Lightmapper { Vector<Light> lights; struct TriangleSort { - uint32_t cell_index; - uint32_t triangle_index; + uint32_t cell_index = 0; + uint32_t triangle_index = 0; bool operator<(const TriangleSort &p_triangle_sort) const { return cell_index < p_triangle_sort.cell_index; //sorting by triangle index in this case makes no sense } @@ -187,44 +187,44 @@ class LightmapperRD : public Lightmapper { void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size); struct RasterPushConstant { - float atlas_size[2]; - float uv_offset[2]; - float to_cell_size[3]; - uint32_t base_triangle; - float to_cell_offset[3]; - float bias; - int32_t grid_size[3]; - uint32_t pad2; + float atlas_size[2] = {}; + float uv_offset[2] = {}; + float to_cell_size[3] = {}; + uint32_t base_triangle = 0; + float to_cell_offset[3] = {}; + float bias = 0.0; + int32_t grid_size[3] = {}; + uint32_t pad2 = 0; }; struct RasterSeamsPushConstant { - uint32_t base_index; - uint32_t slice; - float uv_offset[2]; - uint32_t debug; - float blend; - uint32_t pad[2]; + uint32_t base_index = 0; + uint32_t slice = 0; + float uv_offset[2] = {}; + uint32_t debug = 0; + float blend = 0.0; + uint32_t pad[2] = {}; }; struct PushConstant { - int32_t atlas_size[2]; - uint32_t ray_count; - uint32_t ray_to; + int32_t atlas_size[2] = {}; + uint32_t ray_count = 0; + uint32_t ray_to = 0; - float world_size[3]; - float bias; + float world_size[3] = {}; + float bias = 0.0; - float to_cell_offset[3]; - uint32_t ray_from; + float to_cell_offset[3] = {}; + uint32_t ray_from = 0; - float to_cell_size[3]; - uint32_t light_count; + float to_cell_size[3] = {}; + uint32_t light_count = 0; - int32_t grid_size; - int32_t atlas_slice; - int32_t region_ofs[2]; + int32_t grid_size = 0; + int32_t atlas_slice = 0; + int32_t region_ofs[2] = {}; - float environment_xform[12]; + float environment_xform[12] = {}; }; Vector<Ref<Image>> bake_textures; diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl index 0ff455936e..f8a0cd16de 100644 --- a/modules/lightmapper_rd/lm_common_inc.glsl +++ b/modules/lightmapper_rd/lm_common_inc.glsl @@ -56,8 +56,8 @@ struct Light { float range; float attenuation; - float spot_angle; - float spot_attenuation; + float cos_spot_angle; + float inv_spot_attenuation; bool static_bake; uint pad[3]; diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 8a9adbc5cc..eb9d817f99 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -313,13 +313,16 @@ void main() { if (lights.data[i].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(position - light_pos); - float angle = acos(dot(rel, lights.data[i].direction)); - if (angle > lights.data[i].spot_angle) { + float cos_spot_angle = lights.data[i].cos_spot_angle; + float cos_angle = dot(rel, lights.data[i].direction); + + if (cos_angle < cos_spot_angle) { continue; //invisible, dont try } - float d = clamp(angle / lights.data[i].spot_angle, 0, 1); - attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation); + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation); } } diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp index b2f8d668bf..8a6cdfb131 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.cpp +++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp @@ -246,7 +246,6 @@ int PacketPeerMbedDTLS::get_max_packet_size() const { PacketPeerMbedDTLS::PacketPeerMbedDTLS() { ssl_ctx.instance(); - status = STATUS_DISCONNECTED; } PacketPeerMbedDTLS::~PacketPeerMbedDTLS() { diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h index 0feec04c6e..6554c74a21 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.h +++ b/modules/mbedtls/packet_peer_mbed_dtls.h @@ -44,7 +44,7 @@ private: uint8_t packet_buffer[PACKET_BUFFER_SIZE]; - Status status; + Status status = STATUS_DISCONNECTED; String hostname; Ref<PacketPeerUDP> base; diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp index 046f30588a..cbb532587f 100644 --- a/modules/mbedtls/ssl_context_mbedtls.cpp +++ b/modules/mbedtls/ssl_context_mbedtls.cpp @@ -76,7 +76,6 @@ void CookieContextMbedTLS::clear() { } CookieContextMbedTLS::CookieContextMbedTLS() { - inited = false; } CookieContextMbedTLS::~CookieContextMbedTLS() { @@ -205,7 +204,6 @@ mbedtls_ssl_context *SSLContextMbedTLS::get_context() { } SSLContextMbedTLS::SSLContextMbedTLS() { - inited = false; } SSLContextMbedTLS::~SSLContextMbedTLS() { diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h index d243185726..30632018a8 100644 --- a/modules/mbedtls/ssl_context_mbedtls.h +++ b/modules/mbedtls/ssl_context_mbedtls.h @@ -50,7 +50,7 @@ class CookieContextMbedTLS : public Reference { friend class SSLContextMbedTLS; protected: - bool inited; + bool inited = false; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_cookie_ctx cookie_ctx; @@ -65,7 +65,7 @@ public: class SSLContextMbedTLS : public Reference { protected: - bool inited; + bool inited = false; static PackedByteArray _read_file(String p_path); diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp index 1332d0923c..d7597aa435 100644 --- a/modules/mbedtls/stream_peer_mbedtls.cpp +++ b/modules/mbedtls/stream_peer_mbedtls.cpp @@ -274,7 +274,6 @@ int StreamPeerMbedTLS::get_available_bytes() const { StreamPeerMbedTLS::StreamPeerMbedTLS() { ssl_ctx.instance(); - status = STATUS_DISCONNECTED; } StreamPeerMbedTLS::~StreamPeerMbedTLS() { diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h index ccbbebe4f8..b89d7fb238 100644 --- a/modules/mbedtls/stream_peer_mbedtls.h +++ b/modules/mbedtls/stream_peer_mbedtls.h @@ -36,7 +36,7 @@ class StreamPeerMbedTLS : public StreamPeerSSL { private: - Status status; + Status status = STATUS_DISCONNECTED; String hostname; Ref<StreamPeer> base; diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h index de02ba6003..ce001fc418 100644 --- a/modules/minimp3/audio_stream_mp3.h +++ b/modules/minimp3/audio_stream_mp3.h @@ -78,11 +78,11 @@ class AudioStreamMP3 : public AudioStream { void *data = nullptr; uint32_t data_len = 0; - float sample_rate = 1; + float sample_rate = 1.0; int channels = 1; - float length = 0; + float length = 0.0; bool loop = false; - float loop_offset = 0; + float loop_offset = 0.0; void clear_data(); protected: diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index a9073ea4a0..25b110dc62 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -448,19 +448,7 @@ void MobileVRInterface::process() { }; }; -MobileVRInterface::MobileVRInterface() { - initialized = false; - - // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes - eye_height = 1.85; - intraocular_dist = 6.0; - display_width = 14.5; - display_to_lens = 4.0; - oversample = 1.5; - k1 = 0.215; - k2 = 0.215; - last_ticks = 0; -}; +MobileVRInterface::MobileVRInterface() {} MobileVRInterface::~MobileVRInterface() { // and make sure we cleanup if we haven't already diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index 1afa6c39b6..d28c2196af 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -51,19 +51,21 @@ class MobileVRInterface : public XRInterface { GDCLASS(MobileVRInterface, XRInterface); private: - bool initialized; + bool initialized = false; Basis orientation; - float eye_height; - uint64_t last_ticks; - real_t intraocular_dist; - real_t display_width; - real_t display_to_lens; - real_t oversample; + // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes + float eye_height = 1.85; + uint64_t last_ticks = 0; + + real_t intraocular_dist = 6.0; + real_t display_width = 14.5; + real_t display_to_lens = 4.0; + real_t oversample = 1.5; //@TODO not yet used, these are needed in our distortion shader... - real_t k1; - real_t k2; + real_t k1 = 0.215; + real_t k2 = 0.215; /* logic for processing our sensor data, this was originally in our positional tracker logic but I think @@ -73,9 +75,9 @@ private: Vector3 scale_magneto(const Vector3 &p_magnetometer); Basis combine_acc_mag(const Vector3 &p_grav, const Vector3 &p_magneto); - int mag_count; - bool has_gyro; - bool sensor_first; + int mag_count = 0; + bool has_gyro = false; + bool sensor_first = false; Vector3 last_accerometer_data; Vector3 last_magnetometer_data; Vector3 mag_current_min; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index bd29dc1876..25cc64393a 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3644,7 +3644,7 @@ void CSharpScript::get_members(Set<StringName> *p_members) { /*************** RESOURCE ***************/ -RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 85edd8b9c6..a31135cd32 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -542,7 +542,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override; + RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; void get_recognized_extensions(List<String> *p_extensions) const override; bool handles_type(const String &p_type) const override; String get_resource_type(const String &p_path) const override; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs index 5ef55fea49..774c49e705 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs @@ -86,7 +86,7 @@ namespace GodotTools.Build { case BuildTool.DotnetCli: { - string dotnetCliPath = OS.PathWhich("dotnet"); + string dotnetCliPath = FindBuildEngineOnUnix("dotnet"); if (!string.IsNullOrEmpty(dotnetCliPath)) return (dotnetCliPath, BuildTool.DotnetCli); GD.PushError($"Cannot find executable for '{BuildManager.PropNameDotnetCli}'. Fallback to MSBuild from Mono."); @@ -122,7 +122,11 @@ namespace GodotTools.Build if (OS.IsMacOS) { result.Add("/Library/Frameworks/Mono.framework/Versions/Current/bin/"); + result.Add("/opt/local/bin/"); result.Add("/usr/local/var/homebrew/linked/mono/bin/"); + result.Add("/usr/local/bin/"); + result.Add("/usr/local/bin/dotnet/"); + result.Add("/usr/local/share/dotnet/"); } result.Add("/opt/novell/mono/bin/"); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 90141928ca..0c333d06ef 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -104,7 +104,7 @@ namespace Godot /// <summary> /// The HSV hue of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHSV"/>.</value> public float h { get @@ -145,14 +145,14 @@ namespace Godot } set { - this = FromHsv(value, s, v, a); + this = FromHSV(value, s, v, a); } } /// <summary> /// The HSV saturation of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHSV"/>.</value> public float s { get @@ -166,14 +166,14 @@ namespace Godot } set { - this = FromHsv(h, value, v, a); + this = FromHSV(h, value, v, a); } } /// <summary> /// The HSV value (brightness) of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHSV"/>.</value> public float v { get @@ -182,7 +182,7 @@ namespace Godot } set { - this = FromHsv(h, s, value, a); + this = FromHSV(h, s, value, a); } } @@ -455,7 +455,7 @@ namespace Godot /// </summary> /// <param name="includeAlpha">Whether or not to include alpha. If false, the color is RGB instead of RGBA.</param> /// <returns>A string for the HTML hexadecimal representation of this color.</returns> - public string ToHtml(bool includeAlpha = true) + public string ToHTML(bool includeAlpha = true) { var txt = string.Empty; @@ -532,18 +532,50 @@ namespace Godot } /// <summary> + /// Constructs a color either from an HTML color code or from a + /// standardized color name. Supported + /// color names are the same as the <see cref="Colors"/> constants. + /// </summary> + /// <param name="code">The HTML color code or color name to construct from.</param> + public Color(string code) + { + if (HtmlIsValid(code)) + { + this = FromHTML(code); + } + else + { + this = Named(code); + } + } + + /// <summary> + /// Constructs a color either from an HTML color code or from a + /// standardized color name, with `alpha` on the range of 0 to 1. Supported + /// color names are the same as the <see cref="Colors"/> constants. + /// </summary> + /// <param name="code">The HTML color code or color name to construct from.</param> + /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param> + public Color(string code, float alpha) + { + this = new Color(code); + a = alpha; + } + + /// <summary> /// Constructs a color from the HTML hexadecimal color string in RGBA format. /// </summary> /// <param name="rgba">A string for the HTML hexadecimal representation of this color.</param> - public Color(string rgba) + private static Color FromHTML(string rgba) { + Color c; if (rgba.Length == 0) { - r = 0f; - g = 0f; - b = 0f; - a = 1.0f; - return; + c.r = 0f; + c.g = 0f; + c.b = 0f; + c.a = 1.0f; + return c; } if (rgba[0] == '#') @@ -577,47 +609,48 @@ namespace Godot throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba); } - a = 1.0f; + c.a = 1.0f; if (isShorthand) { - r = ParseCol4(rgba, 0) / 15f; - g = ParseCol4(rgba, 1) / 15f; - b = ParseCol4(rgba, 2) / 15f; + c.r = ParseCol4(rgba, 0) / 15f; + c.g = ParseCol4(rgba, 1) / 15f; + c.b = ParseCol4(rgba, 2) / 15f; if (alpha) { - a = ParseCol4(rgba, 3) / 15f; + c.a = ParseCol4(rgba, 3) / 15f; } } else { - r = ParseCol8(rgba, 0) / 255f; - g = ParseCol8(rgba, 2) / 255f; - b = ParseCol8(rgba, 4) / 255f; + c.r = ParseCol8(rgba, 0) / 255f; + c.g = ParseCol8(rgba, 2) / 255f; + c.b = ParseCol8(rgba, 4) / 255f; if (alpha) { - a = ParseCol8(rgba, 6) / 255f; + c.a = ParseCol8(rgba, 6) / 255f; } } - if (r < 0) + if (c.r < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba); } - if (g < 0) + if (c.g < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba); } - if (b < 0) + if (c.b < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba); } - if (a < 0) + if (c.a < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba); } + return c; } /// <summary> @@ -640,9 +673,8 @@ namespace Godot /// the constants defined in <see cref="Colors"/>. /// </summary> /// <param name="name">The name of the color.</param> - /// <param name="alpha">The alpha (transparency) component represented on the range of 0 to 1. Default: 1.</param> /// <returns>The constructed color.</returns> - public static Color ColorN(string name, float alpha = 1f) + private static Color Named(string name) { name = name.Replace(" ", String.Empty); name = name.Replace("-", String.Empty); @@ -656,9 +688,7 @@ namespace Godot throw new ArgumentOutOfRangeException($"Invalid Color Name: {name}"); } - Color color = Colors.namedColors[name]; - color.a = alpha; - return color; + return Colors.namedColors[name]; } /// <summary> @@ -671,11 +701,11 @@ namespace Godot /// <param name="value">The HSV value (brightness), typically on the range of 0 to 1.</param> /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param> /// <returns>The constructed color.</returns> - public static Color FromHsv(float hue, float saturation, float value, float alpha = 1.0f) + public static Color FromHSV(float hue, float saturation, float value, float alpha = 1.0f) { if (saturation == 0) { - // acp_hromatic (grey) + // Achromatic (grey) return new Color(value, value, value, alpha); } @@ -715,7 +745,7 @@ namespace Godot /// <param name="hue">Output parameter for the HSV hue.</param> /// <param name="saturation">Output parameter for the HSV saturation.</param> /// <param name="value">Output parameter for the HSV value.</param> - public void ToHsv(out float hue, out float saturation, out float value) + public void ToHSV(out float hue, out float saturation, out float value) { float max = (float)Mathf.Max(r, Mathf.Max(g, b)); float min = (float)Mathf.Min(r, Mathf.Min(g, b)); @@ -803,7 +833,8 @@ namespace Godot } // Check if each hex digit is valid. - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) + { if (ParseCol4(color, i) == -1) { return false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index 4dc182fb73..98efa89ef0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -462,18 +462,18 @@ namespace Godot } // <summary> - // Hash the string and return a 32 bits integer. + // Hash the string and return a 32 bits unsigned integer. // </summary> - public static int Hash(this string instance) + public static uint Hash(this string instance) { - int index = 0; - int hashv = 5381; - int c; + uint hash = 5381; - while ((c = instance[index++]) != 0) - hashv = (hashv << 5) + hashv + c; // hash * 33 + c + foreach(uint c in instance) + { + hash = (hash << 5) + hash + c; // hash * 33 + c + } - return hashv; + return hash; } /// <summary> diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index e1d283242c..dafd36c36b 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -189,8 +189,6 @@ void GDMonoLog::initialize() { GDMonoLog::GDMonoLog() { singleton = this; - - log_level_id = -1; } GDMonoLog::~GDMonoLog() { diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h index 9a95e3cb0a..f7a53156ab 100644 --- a/modules/mono/mono_gd/gd_mono_log.h +++ b/modules/mono/mono_gd/gd_mono_log.h @@ -46,9 +46,9 @@ class GDMonoLog { #ifdef GD_MONO_LOG_ENABLED - int log_level_id; + int log_level_id = -1; - FileAccess *log_file; + FileAccess *log_file = nullptr; String log_file_path; bool _try_create_logs_dir(const String &p_logs_dir); diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index 30a0ca3464..f5d401b058 100644 --- a/modules/opensimplex/noise_texture.cpp +++ b/modules/opensimplex/noise_texture.cpp @@ -33,15 +33,6 @@ #include "core/core_string_names.h" NoiseTexture::NoiseTexture() { - update_queued = false; - regen_queued = false; - first_time = true; - - size = Vector2i(512, 512); - seamless = false; - as_normal_map = false; - bump_strength = 8.0; - noise = Ref<OpenSimplexNoise>(); _queue_update(); @@ -225,7 +216,7 @@ void NoiseTexture::set_as_normal_map(bool p_as_normal_map) { } as_normal_map = p_as_normal_map; _queue_update(); - _change_notify(); + notify_property_list_changed(); } bool NoiseTexture::is_normal_map() { diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 170275bd2e..e89479d962 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -47,18 +47,18 @@ private: Thread noise_thread; - bool first_time; - bool update_queued; - bool regen_queued; + bool first_time = true; + bool update_queued = false; + bool regen_queued = false; mutable RID texture; - uint32_t flags; + uint32_t flags = 0; Ref<OpenSimplexNoise> noise; - Vector2i size; - bool seamless; - bool as_normal_map; - float bump_strength; + Vector2i size = Vector2i(512, 512); + bool seamless = false; + bool as_normal_map = false; + float bump_strength = 8.0; void _thread_done(const Ref<Image> &p_image); static void _thread_function(void *p_ud); diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp index e4e2e0613a..3773946112 100644 --- a/modules/opensimplex/open_simplex_noise.cpp +++ b/modules/opensimplex/open_simplex_noise.cpp @@ -33,12 +33,6 @@ #include "core/core_string_names.h" OpenSimplexNoise::OpenSimplexNoise() { - seed = 0; - persistence = 0.5; - octaves = 3; - period = 64; - lacunarity = 2.0; - _init_seeds(); } @@ -131,10 +125,10 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const { float ii = (float)i / (float)p_size; float jj = (float)j / (float)p_size; - ii *= 2.0 * Math_PI; - jj *= 2.0 * Math_PI; + ii *= Math_TAU; + jj *= Math_TAU; - float radius = p_size / (2.0 * Math_PI); + float radius = p_size / Math_TAU; float x = radius * Math::sin(jj); float y = radius * Math::cos(jj); diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h index f18dd4d798..847c157409 100644 --- a/modules/opensimplex/open_simplex_noise.h +++ b/modules/opensimplex/open_simplex_noise.h @@ -48,11 +48,11 @@ class OpenSimplexNoise : public Resource { osn_context contexts[MAX_OCTAVES]; - int seed; - float persistence; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness. - int octaves; // Number of noise layers - float period; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain. - float lacunarity; // Controls period change across octaves. 2 is usually a good value to address all detail levels. + int seed = 0; + float persistence = 0.5; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness. + int octaves = 3; // Number of noise layers + float period = 64.0; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain. + float lacunarity = 2.0; // Controls period change across octaves. 2 is usually a good value to address all detail levels. public: OpenSimplexNoise(); diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 70a3c8b5a9..83f032ca2b 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -46,7 +46,7 @@ enum PVRFLags { PVR_VFLIP = 0x00010000 }; -RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -207,7 +207,7 @@ ResourceFormatPVR::ResourceFormatPVR() { struct PVRTCBlock { //blocks are 64 bits - uint32_t data[2]; + uint32_t data[2] = {}; }; _FORCE_INLINE_ bool is_po2(uint32_t p_input) { diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h index da425c3237..26071ce30f 100644 --- a/modules/pvr/texture_loader_pvr.h +++ b/modules/pvr/texture_loader_pvr.h @@ -36,7 +36,7 @@ class ResourceFormatPVR : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index fe8136ef35..6bae12e7e6 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -365,12 +365,10 @@ Array RegEx::get_names() const { RegEx::RegEx() { general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr); - code = nullptr; } RegEx::RegEx(const String &p_pattern) { general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr); - code = nullptr; compile(p_pattern); } diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 46505855d7..f5773042fb 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -42,8 +42,8 @@ class RegExMatch : public Reference { GDCLASS(RegExMatch, Reference); struct Range { - int start; - int end; + int start = 0; + int end = 0; }; String subject; @@ -72,7 +72,7 @@ class RegEx : public Reference { GDCLASS(RegEx, Reference); void *general_ctx; - void *code; + void *code = nullptr; String pattern; void _pattern_info(uint32_t what, void *where) const; diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index 4b2be47e74..f7bf650354 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -263,16 +263,7 @@ void AudioStreamOGGVorbis::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } -AudioStreamOGGVorbis::AudioStreamOGGVorbis() { - data = nullptr; - data_len = 0; - length = 0; - sample_rate = 1; - channels = 1; - loop_offset = 0; - decode_mem_size = 0; - loop = false; -} +AudioStreamOGGVorbis::AudioStreamOGGVorbis() {} AudioStreamOGGVorbis::~AudioStreamOGGVorbis() { clear_data(); diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h index efc8fc6c27..2bd70a2722 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h @@ -41,11 +41,11 @@ class AudioStreamOGGVorbis; class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled { GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlaybackResampled); - stb_vorbis *ogg_stream; + stb_vorbis *ogg_stream = nullptr; stb_vorbis_alloc ogg_alloc; - uint32_t frames_mixed; - bool active; - int loops; + uint32_t frames_mixed = 0; + bool active = false; + int loops = 0; friend class AudioStreamOGGVorbis; @@ -76,15 +76,15 @@ class AudioStreamOGGVorbis : public AudioStream { friend class AudioStreamPlaybackOGGVorbis; - void *data; - uint32_t data_len; + void *data = nullptr; + uint32_t data_len = 0; - int decode_mem_size; - float sample_rate; - int channels; - float length; - bool loop; - float loop_offset; + int decode_mem_size = 0; + float sample_rate = 1.0; + int channels = 1; + float length = 0.0; + bool loop = false; + float loop_offset = 0.0; void clear_data(); protected: diff --git a/modules/text_server_adv/bitmap_font_adv.cpp b/modules/text_server_adv/bitmap_font_adv.cpp index 01fa94aa7c..df771301e6 100644 --- a/modules/text_server_adv/bitmap_font_adv.cpp +++ b/modules/text_server_adv/bitmap_font_adv.cpp @@ -36,7 +36,7 @@ struct hb_bmp_font_t { BitmapFontDataAdvanced *face = nullptr; - float font_size = 0; + float font_size = 0.0; bool unref = false; /* Whether to destroy bm_face when done. */ }; @@ -340,7 +340,7 @@ Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_bas char_map[idx] = c; } else if (type == "kerning") { KerningPairKey kpk; - float k = 0; + float k = 0.0; if (keys.has("first")) { kpk.A = keys["first"].to_int(); } @@ -540,7 +540,7 @@ Vector2 BitmapFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vecto ERR_FAIL_COND_V(c == nullptr, Vector2()); ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2()); if (c->texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += c->align * (float(p_size) / float(base_size)); cpos.y -= ascent * (float(p_size) / float(base_size)); if (RenderingServer::get_singleton() != nullptr) { diff --git a/modules/text_server_adv/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp index fcefa60d98..5a16158c0f 100644 --- a/modules/text_server_adv/dynamic_font_adv.cpp +++ b/modules/text_server_adv/dynamic_font_adv.cpp @@ -946,7 +946,7 @@ Vector2 DynamicFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vect ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; if (FT_HAS_COLOR(fds->face)) { @@ -977,7 +977,7 @@ Vector2 DynamicFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, in ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; if (FT_HAS_COLOR(fds->face)) { diff --git a/modules/text_server_adv/dynamic_font_adv.h b/modules/text_server_adv/dynamic_font_adv.h index c35dd9390b..cd538cb8e1 100644 --- a/modules/text_server_adv/dynamic_font_adv.h +++ b/modules/text_server_adv/dynamic_font_adv.h @@ -74,14 +74,11 @@ private: uint32_t size : 16; uint32_t outline_size : 16; }; - uint32_t key; + uint32_t key = 0; }; bool operator<(CacheID right) const { return key < right.key; } - CacheID() { - key = 0; - } }; struct DataAtSize { @@ -91,10 +88,10 @@ private: int size = 0; float scale_color_font = 1.f; - float ascent = 0; - float descent = 0; - float underline_position = 0; - float underline_thickness = 0; + float ascent = 0.0; + float descent = 0.0; + float underline_position = 0.0; + float underline_thickness = 0.0; Vector<CharTexture> textures; HashMap<uint32_t, Character> glyph_map; diff --git a/modules/text_server_adv/script_iterator.h b/modules/text_server_adv/script_iterator.h index ad476f7c75..896a0e5c15 100644 --- a/modules/text_server_adv/script_iterator.h +++ b/modules/text_server_adv/script_iterator.h @@ -45,9 +45,9 @@ class ScriptIterator { public: struct ScriptRange { - int start; - int end; - hb_script_t script; + int start = 0; + int end = 0; + hb_script_t script = HB_SCRIPT_COMMON; }; Vector<ScriptRange> script_ranges; diff --git a/modules/text_server_fb/bitmap_font_fb.cpp b/modules/text_server_fb/bitmap_font_fb.cpp index 5c691b7bbd..c9a9cc6eba 100644 --- a/modules/text_server_fb/bitmap_font_fb.cpp +++ b/modules/text_server_fb/bitmap_font_fb.cpp @@ -148,7 +148,7 @@ Error BitmapFontDataFallback::load_from_file(const String &p_filename, int p_bas char_map[idx] = c; } else if (type == "kerning") { KerningPairKey kpk; - float k = 0; + float k = 0.0; if (keys.has("first")) { kpk.A = keys["first"].to_int(); } @@ -321,7 +321,7 @@ Vector2 BitmapFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vecto ERR_FAIL_COND_V(c == nullptr, Vector2()); ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2()); if (c->texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += c->align * (float(p_size) / float(base_size)); cpos.y -= ascent * (float(p_size) / float(base_size)); diff --git a/modules/text_server_fb/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp index 4eecba6ae8..df7756cbd0 100644 --- a/modules/text_server_fb/dynamic_font_fb.cpp +++ b/modules/text_server_fb/dynamic_font_fb.cpp @@ -626,7 +626,7 @@ Vector2 DynamicFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vect ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; @@ -658,7 +658,7 @@ Vector2 DynamicFontDataFallback::draw_glyph_outline(RID p_canvas, int p_size, in ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2()); if (ch.texture_idx != -1) { - Point2 cpos = p_pos; + Point2i cpos = p_pos; cpos += ch.align; Color modulate = p_color; diff --git a/modules/text_server_fb/dynamic_font_fb.h b/modules/text_server_fb/dynamic_font_fb.h index f1cd758f2c..81b18f6af3 100644 --- a/modules/text_server_fb/dynamic_font_fb.h +++ b/modules/text_server_fb/dynamic_font_fb.h @@ -70,14 +70,11 @@ private: uint32_t size : 16; uint32_t outline_size : 16; }; - uint32_t key; + uint32_t key = 0; }; bool operator<(CacheID right) const { return key < right.key; } - CacheID() { - key = 0; - } }; struct DataAtSize { @@ -86,10 +83,10 @@ private: int size = 0; float scale_color_font = 1.f; - float ascent = 0; - float descent = 0; - float underline_position = 0; - float underline_thickness = 0; + float ascent = 0.0; + float descent = 0.0; + float underline_position = 0.0; + float underline_thickness = 0.0; Vector<CharTexture> textures; HashMap<char32_t, Character> char_map; diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 2da9159228..ef53661557 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -56,6 +56,10 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t compressed_pos += 1; count = (c & 0x7f) + 1; + if (output_pos + count * p_pixel_size > output_pos) { + return ERR_PARSE_ERROR; + } + if (c & 0x80) { for (size_t i = 0; i < p_pixel_size; i++) { pixels_w[i] = p_compressed_buffer[compressed_pos]; @@ -79,7 +83,7 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t return OK; } -Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome) { +Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome, size_t p_output_size) { #define TGA_PUT_PIXEL(r, g, b, a) \ int image_data_ofs = ((y * width) + x); \ image_data_w[image_data_ofs * 4 + 0] = r; \ @@ -130,6 +134,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff if (p_is_monochrome) { while (y != y_end) { while (x != x_end) { + if (i > p_output_size) { + return ERR_PARSE_ERROR; + } uint8_t shade = p_buffer[i]; TGA_PUT_PIXEL(shade, shade, shade, 0xff) @@ -143,6 +150,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } else { while (y != y_end) { while (x != x_end) { + if (i > p_output_size) { + return ERR_PARSE_ERROR; + } uint8_t index = p_buffer[i]; uint8_t r = 0x00; uint8_t g = 0x00; @@ -171,6 +181,10 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } else if (p_header.pixel_depth == 24) { while (y != y_end) { while (x != x_end) { + if (i + 2 > p_output_size) { + return ERR_PARSE_ERROR; + } + uint8_t r = p_buffer[i + 2]; uint8_t g = p_buffer[i + 1]; uint8_t b = p_buffer[i + 0]; @@ -186,6 +200,10 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } else if (p_header.pixel_depth == 32) { while (y != y_end) { while (x != x_end) { + if (i + 3 > p_output_size) { + return ERR_PARSE_ERROR; + } + uint8_t a = p_buffer[i + 3]; uint8_t r = p_buffer[i + 2]; uint8_t g = p_buffer[i + 1]; @@ -279,7 +297,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force const uint8_t *src_image_r = src_image.ptr(); const size_t pixel_size = tga_header.pixel_depth >> 3; - const size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size; + size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size; Vector<uint8_t> uncompressed_buffer; uncompressed_buffer.resize(buffer_size); @@ -297,11 +315,12 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force } } else { buffer = src_image_r; + buffer_size = src_image_len; }; if (err == OK) { const uint8_t *palette_r = palette.ptr(); - err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome); + err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome, buffer_size); } } diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index 249e33411e..cb2ce07edd 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -57,23 +57,23 @@ class ImageLoaderTGA : public ImageFormatLoader { }; struct tga_header_s { - uint8_t id_length; - uint8_t color_map_type; + uint8_t id_length = 0; + uint8_t color_map_type = 0; tga_type_e image_type; - uint16_t first_color_entry; - uint16_t color_map_length; - uint8_t color_map_depth; + uint16_t first_color_entry = 0; + uint16_t color_map_length = 0; + uint8_t color_map_depth = 0; - uint16_t x_origin; - uint16_t y_origin; - uint16_t image_width; - uint16_t image_height; - uint8_t pixel_depth; - uint8_t image_descriptor; + uint16_t x_origin = 0; + uint16_t y_origin = 0; + uint16_t image_width = 0; + uint16_t image_height = 0; + uint8_t pixel_depth = 0; + uint8_t image_descriptor = 0; }; static Error decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size); - static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome); + static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome, size_t p_output_size); public: virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale); diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 1026d58b85..4b404eae32 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -645,30 +645,13 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) { #endif VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() { - file = nullptr; - theora_p = 0; - vorbis_p = 0; - videobuf_ready = 0; - playing = false; - frames_pending = 0; - videobuf_time = 0; - paused = false; - - buffering = false; texture = Ref<ImageTexture>(memnew(ImageTexture)); - mix_callback = nullptr; - mix_udata = nullptr; - audio_track = 0; - delay_compensation = 0; - audio_frames_wrote = 0; #ifdef THEORA_USE_THREAD_STREAMING int rb_power = nearest_shift(RB_SIZE_KB * 1024); ring_buffer.resize(rb_power); read_buffer.resize(RB_SIZE_KB * 1024); thread_sem = Semaphore::create(); - thread_exit = false; - thread_eof = false; #endif }; @@ -694,7 +677,7 @@ void VideoStreamTheora::_bind_methods() { //////////// -RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index c315d682da..f92fe2340e 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -52,12 +52,12 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { }; //Image frames[MAX_FRAMES]; - Image::Format format; + Image::Format format = Image::Format::FORMAT_L8; Vector<uint8_t> frame_data; - int frames_pending; - FileAccess *file; + int frames_pending = 0; + FileAccess *file = nullptr; String file_name; - int audio_frames_wrote; + int audio_frames_wrote = 0; Point2i size; int buffer_data(); @@ -65,8 +65,8 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { void video_write(); float get_time() const; - bool theora_eos; - bool vorbis_eos; + bool theora_eos = false; + bool vorbis_eos = false; ogg_sync_state oy; ogg_page og; @@ -74,33 +74,33 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { ogg_stream_state to; th_info ti; th_comment tc; - th_dec_ctx *td; + th_dec_ctx *td = nullptr; vorbis_info vi; vorbis_dsp_state vd; vorbis_block vb; vorbis_comment vc; th_pixel_fmt px_fmt; - double videobuf_time; - int pp_inc; + double videobuf_time = 0; + int pp_inc = 0; - int theora_p; - int vorbis_p; - int pp_level_max; - int pp_level; - int videobuf_ready; + int theora_p = 0; + int vorbis_p = 0; + int pp_level_max = 0; + int pp_level = 0; + int videobuf_ready = 0; - bool playing; - bool buffering; + bool playing = false; + bool buffering = false; - double last_update_time; - double time; - double delay_compensation; + double last_update_time = 0; + double time = 0; + double delay_compensation = 0; Ref<ImageTexture> texture; AudioMixCallback mix_callback; - void *mix_udata; - bool paused; + void *mix_udata = nullptr; + bool paused = false; #ifdef THEORA_USE_THREAD_STREAMING @@ -110,16 +110,16 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback { RingBuffer<uint8_t> ring_buffer; Vector<uint8_t> read_buffer; - bool thread_eof; + bool thread_eof = false; Semaphore *thread_sem; Thread thread; - volatile bool thread_exit; + volatile bool thread_exit = false; static void _streaming_thread(void *ud); #endif - int audio_track; + int audio_track = 0; protected: void clear(); @@ -185,7 +185,7 @@ public: class ResourceFormatLoaderTheora : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp index 8c3be884bd..cff13251ce 100644 --- a/modules/upnp/upnp.cpp +++ b/modules/upnp/upnp.cpp @@ -393,9 +393,6 @@ void UPNP::_bind_methods() { } UPNP::UPNP() { - discover_multicast_if = ""; - discover_local_port = 0; - discover_ipv6 = false; } UPNP::~UPNP() { diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index 9dfa907476..a0cca96bc8 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -41,9 +41,9 @@ class UPNP : public Reference { GDCLASS(UPNP, Reference); private: - String discover_multicast_if; - int discover_local_port; - bool discover_ipv6; + String discover_multicast_if = ""; + int discover_local_port = 0; + bool discover_ipv6 = false; Vector<Ref<UPNPDevice>> devices; diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index 4004f1a04c..219ffd01d3 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -202,24 +202,20 @@ <constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc"> Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES]. </constant> - <constant name="COLORN" value="63" enum="BuiltinFunc"> - Return the [Color] with the given name and alpha ranging from 0 to 1. - [b]Note:[/b] Names are defined in [code]color_names.inc[/code]. - </constant> - <constant name="MATH_SMOOTHSTEP" value="64" enum="BuiltinFunc"> + <constant name="MATH_SMOOTHSTEP" value="63" enum="BuiltinFunc"> Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula: [codeblock] var t = clamp((weight - from) / (to - from), 0.0, 1.0) return t * t * (3.0 - 2.0 * t) [/codeblock] </constant> - <constant name="MATH_POSMOD" value="65" enum="BuiltinFunc"> + <constant name="MATH_POSMOD" value="64" enum="BuiltinFunc"> </constant> - <constant name="MATH_LERP_ANGLE" value="66" enum="BuiltinFunc"> + <constant name="MATH_LERP_ANGLE" value="65" enum="BuiltinFunc"> </constant> - <constant name="TEXT_ORD" value="67" enum="BuiltinFunc"> + <constant name="TEXT_ORD" value="66" enum="BuiltinFunc"> </constant> - <constant name="FUNC_MAX" value="68" enum="BuiltinFunc"> + <constant name="FUNC_MAX" value="67" enum="BuiltinFunc"> Represents the size of the [enum BuiltinFunc] enum. </constant> </constants> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index fe92f59179..2517b17168 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -137,7 +137,6 @@ Ref<VisualScript> VisualScriptNode::get_visual_script() const { } VisualScriptNode::VisualScriptNode() { - breakpoint = false; } //////////////// @@ -145,8 +144,6 @@ VisualScriptNode::VisualScriptNode() { ///////////////////// VisualScriptNodeInstance::VisualScriptNodeInstance() { - sequence_outputs = nullptr; - input_ports = nullptr; } VisualScriptNodeInstance::~VisualScriptNodeInstance() { @@ -2623,14 +2620,8 @@ void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) { } VisualScriptLanguage::VisualScriptLanguage() { - notification = "_notification"; - _step = "_step"; - _subcall = "_subcall"; singleton = this; - _debug_parse_err_node = -1; - _debug_parse_err_file = ""; - _debug_call_stack_pos = 0; int dmcs = GLOBAL_DEF("debug/settings/visual_script/max_call_stack", 1024); ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/visual_script/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/visual_script/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024 diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index bdb3c3a16b..72362e0ef4 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -49,7 +49,7 @@ class VisualScriptNode : public Resource { Ref<VisualScript> script_used; Array default_input_values; - bool breakpoint; + bool breakpoint = false; void _set_default_input_values(Array p_values); Array _get_default_input_values() const; @@ -90,13 +90,9 @@ public: virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) = 0; struct TypeGuess { - Variant::Type type; + Variant::Type type = Variant::NIL; StringName gdclass; Ref<Script> script; - - TypeGuess() { - type = Variant::NIL; - } }; virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const; @@ -114,19 +110,19 @@ class VisualScriptNodeInstance { INPUT_DEFAULT_VALUE_BIT = INPUT_SHIFT, // from unassigned input port, using default value (edited by user) }; - int id; - int sequence_index; - VisualScriptNodeInstance **sequence_outputs; - int sequence_output_count; + int id = 0; + int sequence_index = 0; + VisualScriptNodeInstance **sequence_outputs = nullptr; + int sequence_output_count = 0; Vector<VisualScriptNodeInstance *> dependencies; - int *input_ports; - int input_port_count; - int *output_ports; - int output_port_count; - int working_mem_idx; - int pass_idx; + int *input_ports = nullptr; + int input_port_count = 0; + int *output_ports = nullptr; + int output_port_count = 0; + int working_mem_idx = 0; + int pass_idx = 0; - VisualScriptNode *base; + VisualScriptNode *base = nullptr; public: enum StartMode { @@ -178,7 +174,7 @@ public: uint64_t from_output : 16; uint64_t to_node : 24; }; - uint64_t id; + uint64_t id = 0; }; bool operator<(const SequenceConnection &p_connection) const { @@ -194,7 +190,7 @@ public: uint64_t to_node : 24; uint64_t to_port : 8; }; - uint64_t id; + uint64_t id = 0; }; bool operator<(const DataConnection &p_connection) const { @@ -208,7 +204,7 @@ private: StringName base_type; struct Argument { String name; - Variant::Type type; + Variant::Type type = Variant::Type::NIL; }; struct NodeData { @@ -231,7 +227,7 @@ private: struct Variable { PropertyInfo info; Variant default_value; - bool _export; + bool _export = false; // Add getter & setter options here. }; @@ -388,26 +384,27 @@ public: }; class VisualScriptInstance : public ScriptInstance { - Object *owner; + Object *owner = nullptr; Ref<VisualScript> script; Map<StringName, Variant> variables; // Using variable path, not script. Map<int, VisualScriptNodeInstance *> instances; struct Function { - int node; - int max_stack; - int trash_pos; - int flow_stack_size; - int pass_stack_size; - int node_count; - int argument_count; + int node = 0; + int max_stack = 0; + int trash_pos = 0; + int flow_stack_size = 0; + int pass_stack_size = 0; + int node_count = 0; + int argument_count = 0; }; Map<StringName, Function> functions; Vector<Variant> default_values; - int max_input_args, max_output_args; + int max_input_args = 0; + int max_output_args = 0; StringName source; @@ -479,14 +476,14 @@ class VisualScriptFunctionState : public Reference { ObjectID instance_id; ObjectID script_id; - VisualScriptInstance *instance; + VisualScriptInstance *instance = nullptr; StringName function; Vector<uint8_t> stack; - int working_mem_index; - int variant_stack_size; - VisualScriptNodeInstance *node; - int flow_stack_pos; - int pass; + int working_mem_index = 0; + int variant_stack_size = 0; + VisualScriptNodeInstance *node = nullptr; + int flow_stack_pos = 0; + int pass = 0; Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); @@ -507,25 +504,25 @@ class VisualScriptLanguage : public ScriptLanguage { Map<String, VisualScriptNodeRegisterFunc> register_funcs; struct CallLevel { - Variant *stack; - Variant **work_mem; - const StringName *function; - VisualScriptInstance *instance; - int *current_id; + Variant *stack = nullptr; + Variant **work_mem = nullptr; + const StringName *function = nullptr; + VisualScriptInstance *instance = nullptr; + int *current_id = nullptr; }; - int _debug_parse_err_node; - String _debug_parse_err_file; + int _debug_parse_err_node = -1; + String _debug_parse_err_file = ""; String _debug_error; - int _debug_call_stack_pos; + int _debug_call_stack_pos = 0; int _debug_max_call_stack; CallLevel *_call_stack; public: - StringName notification; + StringName notification = "_notification"; StringName _get_output_port_unsequenced; - StringName _step; - StringName _subcall; + StringName _step = "_step"; + StringName _subcall = "_subcall"; static VisualScriptLanguage *singleton; diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 2558c1d7ec..7ca14fbca8 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -101,7 +101,6 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "str2var", "var2bytes", "bytes2var", - "color_named", "smoothstep", "posmod", "lerp_angle", @@ -200,7 +199,6 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { case LOGIC_MAX: case LOGIC_MIN: case TYPE_CONVERT: - case COLORN: return 2; case MATH_LERP: case MATH_LERP_ANGLE: @@ -476,13 +474,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const return PropertyInfo(Variant::BOOL, "allow_objects"); } } break; - case COLORN: { - if (p_idx == 0) { - return PropertyInfo(Variant::STRING, "name"); - } else { - return PropertyInfo(Variant::FLOAT, "alpha"); - } - } break; case FUNC_MAX: { } } @@ -635,9 +626,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons t = Variant::BOOL; } } break; - case COLORN: { - t = Variant::COLOR; - } break; case FUNC_MAX: { } } @@ -659,7 +647,7 @@ String VisualScriptBuiltinFunc::get_caption() const { void VisualScriptBuiltinFunc::set_func(BuiltinFunc p_which) { ERR_FAIL_INDEX(p_which, FUNC_MAX); func = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1176,15 +1164,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in *r_return = ret; } break; - case VisualScriptBuiltinFunc::COLORN: { - VALIDATE_ARG_NUM(1); - - Color color = Color::named(*p_inputs[0]); - color.a = *p_inputs[1]; - - *r_return = String(color); - - } break; default: { } } @@ -1292,7 +1271,6 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(STR_TO_VAR); BIND_ENUM_CONSTANT(VAR_TO_BYTES); BIND_ENUM_CONSTANT(BYTES_TO_VAR); - BIND_ENUM_CONSTANT(COLORN); BIND_ENUM_CONSTANT(MATH_SMOOTHSTEP); BIND_ENUM_CONSTANT(MATH_POSMOD); BIND_ENUM_CONSTANT(MATH_LERP_ANGLE); @@ -1388,5 +1366,4 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/str2var", create_builtin_func_node<VisualScriptBuiltinFunc::STR_TO_VAR>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/var2bytes", create_builtin_func_node<VisualScriptBuiltinFunc::VAR_TO_BYTES>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/bytes2var", create_builtin_func_node<VisualScriptBuiltinFunc::BYTES_TO_VAR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/color_named", create_builtin_func_node<VisualScriptBuiltinFunc::COLORN>); } diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h index eaa2ef41e2..1fafaf1d98 100644 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ b/modules/visual_script/visual_script_builtin_funcs.h @@ -101,7 +101,6 @@ public: STR_TO_VAR, VAR_TO_BYTES, BYTES_TO_VAR, - COLORN, MATH_SMOOTHSTEP, MATH_POSMOD, MATH_LERP_ANGLE, diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 78e4a7f113..39726a4a58 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -61,7 +61,7 @@ protected: } void _sig_changed() { - _change_notify(); + notify_property_list_changed(); emit_signal("changed"); } @@ -172,7 +172,7 @@ protected: public: void edit(const StringName &p_sig) { sig = p_sig; - _change_notify(); + notify_property_list_changed(); } VisualScriptEditorSignalEdit() { undo_redo = nullptr; } @@ -195,11 +195,10 @@ protected: } void _var_changed() { - _change_notify(); + notify_property_list_changed(); emit_signal("changed"); } void _var_value_changed() { - _change_notify("value"); // So the whole tree is not redrawn, makes editing smoother in general. emit_signal("changed"); } @@ -331,7 +330,7 @@ protected: public: void edit(const StringName &p_var) { var = p_var; - _change_notify(); + notify_property_list_changed(); } VisualScriptEditorVariableEdit() { undo_redo = nullptr; } @@ -3689,16 +3688,23 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_ return; } + Vector2 new_size = p_new_size; + if (graph->is_using_snap()) { + Vector2 snap = Vector2(graph->get_snap(), graph->get_snap()); + Vector2 min_size = (gn->get_minimum_size() + (snap * 0.5)).snapped(snap); + new_size = new_size.snapped(snap).max(min_size); + } + updating_graph = true; graph->set_block_minimum_size_adjust(true); //faster resize undo_redo->create_action(TTR("Resize Comment"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(vsc.ptr(), "set_size", p_new_size / EDSCALE); + undo_redo->add_do_method(vsc.ptr(), "set_size", new_size / EDSCALE); undo_redo->add_undo_method(vsc.ptr(), "set_size", vsc->get_size()); undo_redo->commit_action(); - gn->set_custom_minimum_size(p_new_size); + gn->set_custom_minimum_size(new_size); gn->set_size(Size2(1, 1)); graph->set_block_minimum_size_adjust(false); updating_graph = false; diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 9596fda95c..f673cbb06d 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -63,7 +63,7 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val } expression_dirty = true; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } @@ -1506,13 +1506,20 @@ VisualScriptNodeInstance *VisualScriptExpression::instance(VisualScriptInstance return instance; } +void VisualScriptExpression::reset_state() { + if (nodes) { + memdelete(nodes); + nodes = nullptr; + root = nullptr; + } + + error_str = String(); + error_set = false; + str_ofs = 0; + inputs.clear(); +} + VisualScriptExpression::VisualScriptExpression() { - output_type = Variant::NIL; - expression_dirty = true; - error_set = true; - root = nullptr; - nodes = nullptr; - sequenced = false; } VisualScriptExpression::~VisualScriptExpression() { diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h index 7fe665769d..c35075ea53 100644 --- a/modules/visual_script/visual_script_expression.h +++ b/modules/visual_script/visual_script_expression.h @@ -39,20 +39,18 @@ class VisualScriptExpression : public VisualScriptNode { friend class VisualScriptNodeInstanceExpression; struct Input { - Variant::Type type; + Variant::Type type = Variant::NIL; String name; - - Input() { type = Variant::NIL; } }; Vector<Input> inputs; - Variant::Type output_type; + Variant::Type output_type = Variant::NIL; String expression; - bool sequenced; - int str_ofs; - bool expression_dirty; + bool sequenced = false; + int str_ofs = 0; + bool expression_dirty = true; bool _compile_expression(); @@ -114,7 +112,7 @@ class VisualScriptExpression : public VisualScriptNode { Error _get_token(Token &r_token); String error_str; - bool error_set; + bool error_set = true; struct ENode { enum Type { @@ -131,11 +129,10 @@ class VisualScriptExpression : public VisualScriptNode { TYPE_CALL }; - ENode *next; + ENode *next = nullptr; - Type type; + Type type = Type::TYPE_SELF; - ENode() { next = nullptr; } virtual ~ENode() { if (next) { memdelete(next); @@ -144,17 +141,17 @@ class VisualScriptExpression : public VisualScriptNode { }; struct Expression { - bool is_op; + bool is_op = false; union { Variant::Operator op; - ENode *node; + ENode *node = nullptr; }; }; ENode *_parse_expression(); struct InputNode : public ENode { - int index; + int index = 0; InputNode() { type = TYPE_INPUT; } @@ -168,9 +165,9 @@ class VisualScriptExpression : public VisualScriptNode { }; struct OperatorNode : public ENode { - Variant::Operator op; + Variant::Operator op = Variant::Operator::OP_ADD; - ENode *nodes[2]; + ENode *nodes[2] = { nullptr, nullptr }; OperatorNode() { type = TYPE_OPERATOR; @@ -184,8 +181,8 @@ class VisualScriptExpression : public VisualScriptNode { }; struct IndexNode : public ENode { - ENode *base; - ENode *index; + ENode *base = nullptr; + ENode *index = nullptr; IndexNode() { type = TYPE_INDEX; @@ -193,7 +190,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct NamedIndexNode : public ENode { - ENode *base; + ENode *base = nullptr; StringName name; NamedIndexNode() { @@ -202,7 +199,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct ConstructorNode : public ENode { - Variant::Type data_type; + Variant::Type data_type = Variant::Type::NIL; Vector<ENode *> arguments; ConstructorNode() { @@ -211,7 +208,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct CallNode : public ENode { - ENode *base; + ENode *base = nullptr; StringName method; Vector<ENode *> arguments; @@ -235,7 +232,7 @@ class VisualScriptExpression : public VisualScriptNode { }; struct BuiltinFuncNode : public ENode { - VisualScriptBuiltinFunc::BuiltinFunc func; + VisualScriptBuiltinFunc::BuiltinFunc func = VisualScriptBuiltinFunc::BuiltinFunc::BYTES_TO_VAR; Vector<ENode *> arguments; BuiltinFuncNode() { type = TYPE_BUILTIN_FUNC; @@ -250,8 +247,8 @@ class VisualScriptExpression : public VisualScriptNode { return node; } - ENode *root; - ENode *nodes; + ENode *root = nullptr; + ENode *nodes = nullptr; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -259,6 +256,8 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; public: + virtual void reset_state() override; + virtual int get_output_sequence_port_count() const override; virtual bool has_input_sequence_port() const override; diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 0049e254c4..e2a8323509 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -628,7 +628,7 @@ VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_i bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) { if (String(p_name) == "case_count") { case_values.resize(p_value); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); return true; } @@ -638,7 +638,7 @@ bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) ERR_FAIL_INDEX_V(idx, case_values.size(), false); case_values.write[idx].type = Variant::Type(int(p_value)); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); return true; @@ -677,6 +677,10 @@ void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const { } } +void VisualScriptSwitch::reset_state() { + case_values.clear(); +} + void VisualScriptSwitch::_bind_methods() { } @@ -733,7 +737,7 @@ void VisualScriptTypeCast::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -747,7 +751,7 @@ void VisualScriptTypeCast::set_base_script(const String &p_path) { } script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h index 46a72bb92d..d9c4dedafd 100644 --- a/modules/visual_script/visual_script_flow_control.h +++ b/modules/visual_script/visual_script_flow_control.h @@ -202,6 +202,8 @@ protected: static void _bind_methods(); public: + virtual void reset_state() override; + virtual int get_output_sequence_port_count() const override; virtual bool has_input_sequence_port() const override; diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index d016b938de..b5aacb0506 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -281,7 +281,7 @@ void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) { } basic_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -295,7 +295,7 @@ void VisualScriptFunctionCall::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -309,7 +309,7 @@ void VisualScriptFunctionCall::set_base_script(const String &p_path) { } base_script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -328,7 +328,7 @@ void VisualScriptFunctionCall::set_singleton(const StringName &p_type) { base_type = obj->get_class(); } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -425,7 +425,7 @@ void VisualScriptFunctionCall::set_function(const StringName &p_type) { _update_method_cache(); } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -439,7 +439,7 @@ void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) { } base_path = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -453,7 +453,7 @@ void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) { } call_mode = p_mode; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -476,7 +476,7 @@ void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCa } rpc_call_mode = p_mode; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const { @@ -1067,7 +1067,7 @@ void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) { } basic_type = p_type; - _change_notify(); + notify_property_list_changed(); _update_base_type(); ports_changed_notify(); } @@ -1082,7 +1082,7 @@ void VisualScriptPropertySet::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1096,7 +1096,7 @@ void VisualScriptPropertySet::set_base_script(const String &p_path) { } base_script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1191,7 +1191,7 @@ void VisualScriptPropertySet::set_property(const StringName &p_type) { property = p_type; index = StringName(); _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1206,7 +1206,7 @@ void VisualScriptPropertySet::set_base_path(const NodePath &p_type) { base_path = p_type; _update_base_type(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1221,7 +1221,7 @@ void VisualScriptPropertySet::set_call_mode(CallMode p_mode) { call_mode = p_mode; _update_base_type(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1243,7 +1243,7 @@ void VisualScriptPropertySet::set_index(const StringName &p_type) { } index = p_type; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1259,7 +1259,7 @@ void VisualScriptPropertySet::set_assign_op(AssignOp p_op) { assign_op = p_op; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1760,7 +1760,7 @@ void VisualScriptPropertyGet::set_base_type(const StringName &p_type) { } base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1774,7 +1774,7 @@ void VisualScriptPropertyGet::set_base_script(const String &p_path) { } base_script = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1871,7 +1871,7 @@ void VisualScriptPropertyGet::set_property(const StringName &p_type) { property = p_type; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1885,7 +1885,7 @@ void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) { } base_path = p_type; - _change_notify(); + notify_property_list_changed(); _update_base_type(); ports_changed_notify(); } @@ -1900,7 +1900,7 @@ void VisualScriptPropertyGet::set_call_mode(CallMode p_mode) { } call_mode = p_mode; - _change_notify(); + notify_property_list_changed(); _update_base_type(); ports_changed_notify(); } @@ -1915,7 +1915,7 @@ void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) { } basic_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1937,7 +1937,7 @@ void VisualScriptPropertyGet::set_index(const StringName &p_type) { } index = p_type; _update_cache(); - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2261,7 +2261,7 @@ void VisualScriptEmitSignal::set_signal(const StringName &p_type) { name = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index ae2b548f21..fed6637acb 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -57,7 +57,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value arguments.write[i].type = Variant::NIL; } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } if (String(p_name).begins_with("argument_")) { @@ -303,6 +303,14 @@ VisualScriptNodeInstance *VisualScriptFunction::instance(VisualScriptInstance *p return instance; } +void VisualScriptFunction::reset_state() { + arguments.clear(); + stack_size = 256; + stack_less = false; + sequenced = true; + rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; +} + VisualScriptFunction::VisualScriptFunction() { stack_size = 256; stack_less = false; @@ -312,7 +320,7 @@ VisualScriptFunction::VisualScriptFunction() { void VisualScriptFunction::set_stack_less(bool p_enable) { stack_less = p_enable; - _change_notify(); + notify_property_list_changed(); } bool VisualScriptFunction::is_stack_less() const { @@ -421,7 +429,7 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) { inputports.write[i].type = Variant::NIL; } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } if (String(p_name).begins_with("input_") && is_input_port_editable()) { @@ -457,7 +465,7 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) { outputports.write[i].type = Variant::NIL; } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); return true; } if (String(p_name).begins_with("output_") && is_output_port_editable()) { @@ -578,7 +586,7 @@ void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String & } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) { @@ -590,7 +598,7 @@ void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type inputports.write[p_idx].type = p_type; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) { @@ -602,7 +610,7 @@ void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name inputports.write[p_idx].name = p_name; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::remove_input_data_port(int p_argidx) { @@ -615,7 +623,7 @@ void VisualScriptLists::remove_input_data_port(int p_argidx) { inputports.remove(p_argidx); ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } // output data port interaction @@ -634,7 +642,7 @@ void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String } ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) { @@ -646,7 +654,7 @@ void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_typ outputports.write[p_idx].type = p_type; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) { @@ -658,7 +666,7 @@ void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_nam outputports.write[p_idx].name = p_name; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } void VisualScriptLists::remove_output_data_port(int p_argidx) { @@ -671,7 +679,7 @@ void VisualScriptLists::remove_output_data_port(int p_argidx) { outputports.remove(p_argidx); ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } // sequences @@ -687,6 +695,13 @@ bool VisualScriptLists::is_sequenced() const { return sequenced; } +void VisualScriptLists::reset_state() { + inputports.clear(); + outputports.clear(); + sequenced = false; + flags = 0; +} + VisualScriptLists::VisualScriptLists() { // initialize sequenced = false; @@ -1433,7 +1448,7 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) { Callable::CallError ce; Variant::construct(type, value, nullptr, 0, ce); ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } Variant::Type VisualScriptConstant::get_constant_type() const { @@ -1764,7 +1779,7 @@ String VisualScriptGlobalConstant::get_caption() const { void VisualScriptGlobalConstant::set_global_constant(int p_which) { index = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1850,7 +1865,7 @@ String VisualScriptClassConstant::get_caption() const { void VisualScriptClassConstant::set_class_constant(const StringName &p_which) { name = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1876,7 +1891,7 @@ void VisualScriptClassConstant::set_base_type(const StringName &p_which) { } else { name = ""; } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -1983,7 +1998,7 @@ String VisualScriptBasicTypeConstant::get_text() const { void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) { name = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2010,7 +2025,7 @@ void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { } else { name = ""; } - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2140,7 +2155,7 @@ String VisualScriptMathConstant::get_caption() const { void VisualScriptMathConstant::set_math_constant(MathConstant p_which) { constant = p_which; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2233,7 +2248,7 @@ String VisualScriptEngineSingleton::get_caption() const { void VisualScriptEngineSingleton::set_singleton(const String &p_string) { singleton = p_string; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2342,7 +2357,7 @@ String VisualScriptSceneNode::get_caption() const { void VisualScriptSceneNode::set_node_path(const NodePath &p_path) { path = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -2620,7 +2635,7 @@ String VisualScriptResourcePath::get_caption() const { void VisualScriptResourcePath::set_resource_path(const String &p_path) { path = p_path; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -3748,7 +3763,7 @@ void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) { type = p_type; _update_elements(); ports_changed_notify(); - _change_notify(); //to make input appear/disappear + notify_property_list_changed(); //to make input appear/disappear } Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const { diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index ae5e04d096..7392443e4e 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -99,6 +99,8 @@ public: virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) override; + virtual void reset_state() override; + VisualScriptFunction(); }; @@ -134,6 +136,8 @@ protected: static void _bind_methods(); public: + virtual void reset_state() override; + virtual bool is_output_port_editable() const; virtual bool is_output_port_name_editable() const; virtual bool is_output_port_type_editable() const; diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index 6c9af4e600..25fabd7b87 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -152,7 +152,7 @@ void VisualScriptYield::set_yield_mode(YieldMode p_mode) { } yield_mode = p_mode; ports_changed_notify(); - _change_notify(); + notify_property_list_changed(); } VisualScriptYield::YieldMode VisualScriptYield::get_yield_mode() { @@ -359,7 +359,7 @@ void VisualScriptYieldSignal::set_base_type(const StringName &p_type) { base_type = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -374,7 +374,7 @@ void VisualScriptYieldSignal::set_signal(const StringName &p_type) { signal = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -389,7 +389,7 @@ void VisualScriptYieldSignal::set_base_path(const NodePath &p_type) { base_path = p_type; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } @@ -404,7 +404,7 @@ void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) { call_mode = p_mode; - _change_notify(); + notify_property_list_changed(); ports_changed_notify(); } diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 5d8245c64c..7c16a1df34 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -429,7 +429,7 @@ void VideoStreamWebm::set_audio_track(int p_track) { //////////// -RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index cb3cf58850..60e02ab38b 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -126,7 +126,7 @@ public: class ResourceFormatLoaderWebm : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp index 9f2b084cb1..dfbec80c86 100644 --- a/modules/webrtc/webrtc_data_channel_js.cpp +++ b/modules/webrtc/webrtc_data_channel_js.cpp @@ -182,16 +182,9 @@ bool WebRTCDataChannelJS::is_negotiated() const { } WebRTCDataChannelJS::WebRTCDataChannelJS() { - queue_count = 0; - _was_string = false; - _write_mode = WRITE_MODE_BINARY; - _js_id = 0; } WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) { - queue_count = 0; - _was_string = false; - _write_mode = WRITE_MODE_BINARY; _js_id = js_id; godot_js_rtc_datachannel_connect(js_id, this, &_on_open, &_on_message, &_on_error, &_on_close); diff --git a/modules/webrtc/webrtc_data_channel_js.h b/modules/webrtc/webrtc_data_channel_js.h index 8c56b62303..db58ebccff 100644 --- a/modules/webrtc/webrtc_data_channel_js.h +++ b/modules/webrtc/webrtc_data_channel_js.h @@ -42,16 +42,16 @@ private: String _label; String _protocol; - bool _was_string; - WriteMode _write_mode; + bool _was_string = false; + WriteMode _write_mode = WRITE_MODE_BINARY; enum { PACKET_BUFFER_SIZE = 65536 - 5 // 4 bytes for the size, 1 for for type }; - int _js_id; + int _js_id = 0; RingBuffer<uint8_t> in_buffer; - int queue_count; + int queue_count = 0; uint8_t packet_buffer[PACKET_BUFFER_SIZE]; static void _on_open(void *p_obj); diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index aec01a1eea..25b6d6ef0e 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -140,11 +140,7 @@ Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffe } EMWSClient::EMWSClient() { - _in_buf_size = DEF_BUF_SHIFT; - _in_pkt_size = DEF_PKT_SHIFT; - _is_connecting = false; _peer = Ref<EMWSPeer>(memnew(EMWSPeer)); - _js_id = 0; } EMWSClient::~EMWSClient() { diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index fdf7a231d2..2ab7dc83d0 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -41,10 +41,10 @@ class EMWSClient : public WebSocketClient { GDCIIMPL(EMWSClient, WebSocketClient); private: - int _js_id; - bool _is_connecting; - int _in_buf_size; - int _in_pkt_size; + int _js_id = 0; + bool _is_connecting = false; + int _in_buf_size = DEF_BUF_SHIFT; + int _in_pkt_size = DEF_PKT_SHIFT; static void _esws_on_connect(void *obj, char *proto); static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string); diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 496c1edc04..5e75e10d68 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -106,8 +106,6 @@ void EMWSPeer::set_no_delay(bool p_enabled) { } EMWSPeer::EMWSPeer() { - peer_sock = -1; - write_mode = WRITE_MODE_BINARY; close(); }; diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 07f61b62a0..abe5bf2bdb 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -56,12 +56,12 @@ class EMWSPeer : public WebSocketPeer { GDCIIMPL(EMWSPeer, WebSocketPeer); private: - int peer_sock; - WriteMode write_mode; + int peer_sock = -1; + WriteMode write_mode = WRITE_MODE_BINARY; Vector<uint8_t> _packet_buffer; PacketBuffer<uint8_t> _in_buffer; - uint8_t _is_string; + uint8_t _is_string = 0; public: Error read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string); diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp index eb0252e6d1..425013f811 100644 --- a/modules/websocket/websocket_client.cpp +++ b/modules/websocket/websocket_client.cpp @@ -33,7 +33,6 @@ GDCINULL(WebSocketClient); WebSocketClient::WebSocketClient() { - verify_ssl = true; } WebSocketClient::~WebSocketClient() { diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 78b77b89cd..0225c9b3d3 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -42,7 +42,7 @@ class WebSocketClient : public WebSocketMultiplayerPeer { protected: Ref<WebSocketPeer> _peer; - bool verify_ssl; + bool verify_ssl = true; Ref<X509Certificate> ssl_cert; static void _bind_methods(); diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index f94642475c..011cb86535 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -33,15 +33,6 @@ #include "core/os/os.h" WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() { - _is_multiplayer = false; - _peer_id = 0; - _target_peer = 0; - _refusing = false; - - _current_packet.source = 0; - _current_packet.destination = 0; - _current_packet.size = 0; - _current_packet.data = nullptr; } WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() { diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index e593163b7c..48a6607d89 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -55,20 +55,20 @@ protected: }; struct Packet { - int source; - int destination; - uint8_t *data; - uint32_t size; + int source = 0; + int destination = 0; + uint8_t *data = nullptr; + uint32_t size = 0; }; List<Packet> _incoming_packets; Map<int, Ref<WebSocketPeer>> _peer_map; Packet _current_packet; - bool _is_multiplayer; - int _target_peer; - int _peer_id; - int _refusing; + bool _is_multiplayer = false; + int _target_peer = 0; + int _peer_id = 0; + int _refusing = false; static void _bind_methods(); diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 3e2f48e9b3..a075ae3982 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -337,11 +337,6 @@ Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer } WSLClient::WSLClient() { - _in_buf_size = DEF_BUF_SHIFT; - _in_pkt_size = DEF_PKT_SHIFT; - _out_buf_size = DEF_BUF_SHIFT; - _out_pkt_size = DEF_PKT_SHIFT; - _peer.instance(); _tcp.instance(); disconnect_from_host(); diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 8712b57f2c..e7c91ed333 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -44,27 +44,27 @@ class WSLClient : public WebSocketClient { GDCIIMPL(WSLClient, WebSocketClient); private: - int _in_buf_size; - int _in_pkt_size; - int _out_buf_size; - int _out_pkt_size; + int _in_buf_size = DEF_BUF_SHIFT; + int _in_pkt_size = DEF_PKT_SHIFT; + int _out_buf_size = DEF_BUF_SHIFT; + int _out_pkt_size = DEF_PKT_SHIFT; Ref<WSLPeer> _peer; Ref<StreamPeerTCP> _tcp; Ref<StreamPeer> _connection; CharString _request; - int _requested; + int _requested = 0; uint8_t _resp_buf[WSL_MAX_HEADER_SIZE]; - int _resp_pos; + int _resp_pos = 0; String _response; String _key; String _host; Vector<String> _protocols; - bool _use_ssl; + bool _use_ssl = false; void _do_handshake(); bool _verify_headers(String &r_protocol); diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 9d016e1139..dbbf86d0da 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -329,10 +329,6 @@ void WSLPeer::invalidate() { } WSLPeer::WSLPeer() { - _data = nullptr; - _is_string = 0; - close_code = -1; - write_mode = WRITE_MODE_BINARY; } WSLPeer::~WSLPeer() { diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index 01efa4b21e..5e6a7e8554 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -48,29 +48,17 @@ class WSLPeer : public WebSocketPeer { public: struct PeerData { - bool polling; - bool destroy; - bool valid; - bool is_server; - bool closing; - void *obj; - void *peer; + bool polling = false; + bool destroy = false; + bool valid = false; + bool is_server = false; + bool closing = false; + void *obj = nullptr; + void *peer = nullptr; Ref<StreamPeer> conn; Ref<StreamPeerTCP> tcp; - int id; - wslay_event_context_ptr ctx; - - PeerData() { - polling = false; - destroy = false; - valid = false; - is_server = false; - id = 1; - ctx = nullptr; - obj = nullptr; - closing = false; - peer = nullptr; - } + int id = 1; + wslay_event_context_ptr ctx = nullptr; }; static String compute_key_response(String p_key); @@ -80,17 +68,17 @@ private: static bool _wsl_poll(struct PeerData *p_data); static void _wsl_destroy(struct PeerData **p_data); - struct PeerData *_data; - uint8_t _is_string; + struct PeerData *_data = nullptr; + uint8_t _is_string = 0; // Our packet info is just a boolean (is_string), using uint8_t for it. PacketBuffer<uint8_t> _in_buffer; Vector<uint8_t> _packet_buffer; - WriteMode write_mode; + WriteMode write_mode = WRITE_MODE_BINARY; public: - int close_code; + int close_code = -1; String close_reason; void poll(); // Used by client and server. diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 9df076bf3f..437eb2061b 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -34,15 +34,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" -WSLServer::PendingPeer::PendingPeer() { - use_ssl = false; - time = 0; - has_request = false; - response_sent = 0; - req_pos = 0; - memset(req_buf, 0, sizeof(req_buf)); -} - bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) { Vector<String> psa = String((char *)req_buf).split("\r\n"); int len = psa.size(); @@ -310,10 +301,6 @@ Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer } WSLServer::WSLServer() { - _in_buf_size = DEF_BUF_SHIFT; - _in_pkt_size = DEF_PKT_SHIFT; - _out_buf_size = DEF_BUF_SHIFT; - _out_pkt_size = DEF_PKT_SHIFT; _server.instance(); } diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index 8b2d4d3a04..75669e12ee 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -53,26 +53,24 @@ private: public: Ref<StreamPeerTCP> tcp; Ref<StreamPeer> connection; - bool use_ssl; + bool use_ssl = false; - int time; - uint8_t req_buf[WSL_MAX_HEADER_SIZE]; - int req_pos; + int time = 0; + uint8_t req_buf[WSL_MAX_HEADER_SIZE] = {}; + int req_pos = 0; String key; String protocol; - bool has_request; + bool has_request = false; CharString response; - int response_sent; - - PendingPeer(); + int response_sent = 0; Error do_handshake(const Vector<String> p_protocols); }; - int _in_buf_size; - int _in_pkt_size; - int _out_buf_size; - int _out_pkt_size; + int _in_buf_size = DEF_BUF_SHIFT; + int _in_pkt_size = DEF_PKT_SHIFT; + int _out_buf_size = DEF_BUF_SHIFT; + int _out_pkt_size = DEF_PKT_SHIFT; List<Ref<PendingPeer>> _pending; Ref<TCP_Server> _server; diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 9f6e7efb27..880fe2df61 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -163,8 +163,8 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver *r_uvs = (float *)malloc(sizeof(float) * output.vertexCount * 2); *r_indices = (int *)malloc(sizeof(int) * output.indexCount); - float max_x = 0; - float max_y = 0; + float max_x = 0.0; + float max_y = 0.0; for (uint32_t i = 0; i < output.vertexCount; i++) { (*r_vertices)[i] = output.vertexArray[i].xref; (*r_uvs)[i * 2 + 0] = output.vertexArray[i].uv[0] / w; diff --git a/platform/android/detect.py b/platform/android/detect.py index 650606ff8b..0e696024a9 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -13,7 +13,7 @@ def get_name(): def can_build(): - return "ANDROID_NDK_ROOT" in os.environ + return ("ANDROID_NDK_ROOT" in os.environ) or ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ) def get_platform(platform): @@ -24,13 +24,36 @@ def get_opts(): from SCons.Variables import BoolVariable, EnumVariable return [ - ("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)), + ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()), + ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()), ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"), EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")), BoolVariable("android_neon", "Enable NEON support (armv7 only)", True), ] +# Return the ANDROID_SDK_ROOT environment variable. +# While ANDROID_HOME has been deprecated, it's used as a fallback for backward +# compatibility purposes. +def get_android_sdk_root(): + if "ANDROID_SDK_ROOT" in os.environ: + return os.environ.get("ANDROID_SDK_ROOT", 0) + else: + return os.environ.get("ANDROID_HOME", 0) + + +# Return the ANDROID_NDK_ROOT environment variable. +# If the env variable is already defined, we use it with the expectation that +# the user knows what they're doing (e.g: testing a new NDK version). +# Otherwise, we generate one for this build using the ANDROID_SDK_ROOT env +# variable and the project ndk version. +def get_android_ndk_root(): + if "ANDROID_NDK_ROOT" in os.environ: + return os.environ.get("ANDROID_NDK_ROOT", 0) + else: + return get_android_sdk_root() + "/ndk/" + get_project_ndk_version() + + def get_flags(): return [ ("tools", False), @@ -47,7 +70,31 @@ def create(env): return env.Clone(tools=tools) +# Check if ANDROID_NDK_ROOT is valid. +# If not, install the ndk using ANDROID_SDK_ROOT and sdkmanager. +def install_ndk_if_needed(env): + print("Checking for Android NDK...") + env_ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"]) + if env_ndk_version is None: + # Reinstall the ndk and update ANDROID_NDK_ROOT. + print("Installing Android NDK...") + if env["ANDROID_SDK_ROOT"] is None: + raise Exception("Invalid ANDROID_SDK_ROOT environment variable.") + + import subprocess + + extension = ".bat" if os.name == "nt" else "" + sdkmanager_path = env["ANDROID_SDK_ROOT"] + "/cmdline-tools/latest/bin/sdkmanager" + extension + ndk_download_args = "ndk;" + get_project_ndk_version() + subprocess.check_call([sdkmanager_path, ndk_download_args]) + + env["ANDROID_NDK_ROOT"] = env["ANDROID_SDK_ROOT"] + "/ndk/" + get_project_ndk_version() + print("ANDROID_NDK_ROOT: " + env["ANDROID_NDK_ROOT"]) + + def configure(env): + install_ndk_if_needed(env) + # Workaround for MinGW. See: # http://www.scons.org/wiki/LongCmdLinesOnWin32 if os.name == "nt": @@ -270,7 +317,7 @@ def configure(env): # Link flags - ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"]) + ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"]) if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"): env.Append(LINKFLAGS=["-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"]) else: @@ -323,8 +370,14 @@ def configure(env): env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"]) +# Return the project NDK version. +# This is kept in sync with the value in 'platform/android/java/app/config.gradle'. +def get_project_ndk_version(): + return "21.3.6528147" + + # Return NDK version string in source.properties (adapted from the Chromium project). -def get_ndk_version(path): +def get_env_ndk_version(path): if path is None: return None prop_file_path = os.path.join(path, "source.properties") diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 53d11fda5b..814cc30613 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -98,6 +98,8 @@ android { disable 'MissingTranslation', 'UnusedResources' } + ndkVersion versions.ndkVersion + packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 80cf6f7ede..8d3aa8a6b0 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -7,7 +7,8 @@ ext.versions = [ supportCoreUtils : '1.0.0', kotlinVersion : '1.4.10', v4Support : '1.0.0', - javaVersion : 1.8 + javaVersion : 1.8, + ndkVersion : '21.3.6528147' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated. ] diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 89ce3d15e6..6260cadffb 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -68,7 +68,7 @@ android { File sconsExecutableFile = null def sconsName = "scons" def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows() - ? [".bat", ".exe"] + ? [".bat", ".cmd", ".ps1", ".exe"] : [""]) logger.lifecycle("Looking for $sconsName executable path") for (ext in sconsExts) { 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 3368363ce7..435b8b325f 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 @@ -38,6 +38,8 @@ import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; import android.os.Build; import android.util.Log; +import android.util.SparseArray; +import android.util.SparseIntArray; import android.view.InputDevice; import android.view.InputDevice.MotionRange; import android.view.KeyEvent; @@ -46,17 +48,24 @@ import android.view.MotionEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; /** * Handles input related events for the {@link GodotRenderView} view. */ public class GodotInputHandler implements InputDeviceListener { - private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>(); - private final GodotRenderView mRenderView; private final InputManagerCompat mInputManager; + private final String tag = this.getClass().getSimpleName(); + + private final SparseIntArray mJoystickIds = new SparseIntArray(4); + private final SparseArray<Joystick> mJoysticksDevices = new SparseArray<Joystick>(4); + public GodotInputHandler(GodotRenderView godotView) { mRenderView = godotView; mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext()); @@ -82,19 +91,20 @@ public class GodotInputHandler implements InputDeviceListener { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { return false; - }; + } int source = event.getSource(); if (isKeyEvent_GameDevice(source)) { - final int button = getGodotButton(keyCode); - final int device_id = findJoystickDevice(event.getDeviceId()); - // Check if the device exists - if (device_id > -1) { + final int deviceId = event.getDeviceId(); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + final int button = getGodotButton(keyCode); + final int godotJoyId = mJoystickIds.get(deviceId); + queueEvent(new Runnable() { @Override public void run() { - GodotLib.joybutton(device_id, button, false); + GodotLib.joybutton(godotJoyId, button, false); } }); } @@ -107,7 +117,7 @@ public class GodotInputHandler implements InputDeviceListener { GodotLib.key(keyCode, scanCode, chr, false); } }); - }; + } return true; } @@ -122,24 +132,25 @@ public class GodotInputHandler implements InputDeviceListener { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { return false; - }; + } int source = event.getSource(); //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); + final int deviceId = event.getDeviceId(); + // Check if source is a game device and that the device is a registered gamepad if (isKeyEvent_GameDevice(source)) { if (event.getRepeatCount() > 0) // ignore key echo return true; - final int button = getGodotButton(keyCode); - final int device_id = findJoystickDevice(event.getDeviceId()); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + final int button = getGodotButton(keyCode); + final int godotJoyId = mJoystickIds.get(deviceId); - // Check if the device exists - if (device_id > -1) { queueEvent(new Runnable() { @Override public void run() { - GodotLib.joybutton(device_id, button, true); + GodotLib.joybutton(godotJoyId, button, true); } }); } @@ -152,7 +163,7 @@ public class GodotInputHandler implements InputDeviceListener { GodotLib.key(keyCode, scanCode, chr, true); } }); - }; + } return true; } @@ -203,38 +214,52 @@ public class GodotInputHandler implements InputDeviceListener { } public boolean onGenericMotionEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - final int device_id = findJoystickDevice(event.getDeviceId()); - + if (event.isFromSource(InputDevice.SOURCE_JOYSTICK) && event.getAction() == MotionEvent.ACTION_MOVE) { // Check if the device exists - if (device_id > -1) { - Joystick joy = mJoysticksDevices.get(device_id); - - for (int i = 0; i < joy.axes.size(); i++) { - InputDevice.MotionRange range = joy.axes.get(i); - final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f; - final int idx = i; - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyaxis(device_id, idx, value); - } - }); + final int deviceId = event.getDeviceId(); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + final int godotJoyId = mJoystickIds.get(deviceId); + Joystick joystick = mJoysticksDevices.get(deviceId); + + for (int i = 0; i < joystick.axes.size(); i++) { + final int axis = joystick.axes.get(i); + final float value = event.getAxisValue(axis); + /** + * As all axes are polled for each event, only fire an axis event if the value has actually changed. + * Prevents flooding Godot with repeated events. + */ + if (joystick.axesValues.indexOfKey(axis) < 0 || (float)joystick.axesValues.get(axis) != value) { + // save value to prevent repeats + joystick.axesValues.put(axis, value); + final int godotAxisIdx = i; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyaxis(godotJoyId, godotAxisIdx, value); + //Log.i(tag, "GodotLib.joyaxis("+godotJoyId+", "+godotAxisIdx+", "+value+");"); + } + }); + } } - for (int i = 0; i < joy.hats.size(); i += 2) { - final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); - final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis())); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyhat(device_id, hatX, hatY); - } - }); + if (joystick.hasAxisHat) { + final int hatX = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_X)); + final int hatY = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_Y)); + if (joystick.hatX != hatX || joystick.hatY != hatY) { + joystick.hatX = hatX; + joystick.hatY = hatY; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyhat(godotJoyId, hatX, hatY); + //Log.i(tag, "GodotLib.joyhat("+godotJoyId+", "+hatX+", "+hatY+");"); + } + }); + } } return true; } - } else if ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) { + } else if (event.isFromSource(InputDevice.SOURCE_STYLUS)) { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); @@ -245,6 +270,7 @@ public class GodotInputHandler implements InputDeviceListener { } }); return true; + } else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return handleMouseEvent(event); @@ -266,67 +292,98 @@ public class GodotInputHandler implements InputDeviceListener { } } + private int assignJoystickIdNumber(int deviceId) { + int godotJoyId = 0; + while (mJoystickIds.indexOfValue(godotJoyId) >= 0) { + godotJoyId++; + } + mJoystickIds.put(deviceId, godotJoyId); + return godotJoyId; + } + @Override public void onInputDeviceAdded(int deviceId) { - int id = findJoystickDevice(deviceId); - // Check if the device has not been already added - if (id < 0) { - InputDevice device = mInputManager.getInputDevice(deviceId); - //device can be null if deviceId is not found - if (device != null) { - int sources = device.getSources(); - if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || - ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) { - id = mJoysticksDevices.size(); - - Joystick joy = new Joystick(); - joy.device_id = deviceId; - joy.name = device.getName(); - joy.axes = new ArrayList<InputDevice.MotionRange>(); - joy.hats = new ArrayList<InputDevice.MotionRange>(); - - List<InputDevice.MotionRange> ranges = device.getMotionRanges(); - Collections.sort(ranges, new RangeComparator()); - - for (InputDevice.MotionRange range : ranges) { - if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) { - joy.hats.add(range); - } else { - joy.axes.add(range); - } - } - mJoysticksDevices.add(joy); + if (mJoystickIds.indexOfKey(deviceId) >= 0) { + return; + } + + InputDevice device = mInputManager.getInputDevice(deviceId); + //device can be null if deviceId is not found + if (device == null) { + return; + } + + int sources = device.getSources(); + + // Device may not be a joystick or gamepad + if ((sources & InputDevice.SOURCE_GAMEPAD) != InputDevice.SOURCE_GAMEPAD && + (sources & InputDevice.SOURCE_JOYSTICK) != InputDevice.SOURCE_JOYSTICK) { + return; + } + + // Assign first available number. Re-use numbers where possible. + final int id = assignJoystickIdNumber(deviceId); + + final Joystick joystick = new Joystick(); + joystick.device_id = deviceId; + joystick.name = device.getName(); + + //Helps with creating new joypad mappings. + Log.i(tag, "=== New Input Device: " + joystick.name); - final int device_id = id; - final String name = joy.name; - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyconnectionchanged(device_id, true, name); - } - }); + Set<Integer> already = new HashSet<Integer>(); + for (InputDevice.MotionRange range : device.getMotionRanges()) { + boolean isJoystick = range.isFromSource(InputDevice.SOURCE_JOYSTICK); + boolean isGamepad = range.isFromSource(InputDevice.SOURCE_GAMEPAD); + //Log.i(tag, "axis: "+range.getAxis()+ ", isJoystick: "+isJoystick+", isGamepad: "+isGamepad); + if (!isJoystick && !isGamepad) { + continue; + } + final int axis = range.getAxis(); + if (axis == MotionEvent.AXIS_HAT_X || axis == MotionEvent.AXIS_HAT_Y) { + joystick.hasAxisHat = true; + } else { + if (!already.contains(axis)) { + already.add(axis); + joystick.axes.add(axis); + } else { + Log.w(tag, " - DUPLICATE AXIS VALUE IN LIST: " + axis); } } } + Collections.sort(joystick.axes); + for (int idx = 0; idx < joystick.axes.size(); idx++) { + //Helps with creating new joypad mappings. + Log.i(tag, " - Mapping Android axis " + joystick.axes.get(idx) + " to Godot axis " + idx); + } + mJoysticksDevices.put(deviceId, joystick); + + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, true, joystick.name); + } + }); } @Override public void onInputDeviceRemoved(int deviceId) { - final int device_id = findJoystickDevice(deviceId); - - // Check if the evice has not been already removed - if (device_id > -1) { - mJoysticksDevices.remove(device_id); - - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyconnectionchanged(device_id, false, ""); - } - }); + // Check if the device has not been already removed + if (mJoystickIds.indexOfKey(deviceId) < 0) { + return; } + final int godotJoyId = mJoystickIds.get(deviceId); + mJoystickIds.delete(deviceId); + mJoysticksDevices.delete(deviceId); + + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(godotJoyId, false, ""); + } + }); } @Override @@ -407,16 +464,6 @@ public class GodotInputHandler implements InputDeviceListener { return button; } - private int findJoystickDevice(int device_id) { - for (int i = 0; i < mJoysticksDevices.size(); i++) { - if (mJoysticksDevices.get(i).device_id == device_id) { - return i; - } - } - - return -1; - } - private boolean handleMouseEvent(final MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_HOVER_ENTER: diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java index 82bd45ee3f..4b7318c718 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java @@ -30,9 +30,10 @@ package org.godotengine.godot.input; -import android.view.InputDevice.MotionRange; +import android.util.SparseArray; import java.util.ArrayList; +import java.util.List; /** * POJO class to represent a Joystick input device. @@ -40,6 +41,12 @@ import java.util.ArrayList; class Joystick { int device_id; String name; - ArrayList<MotionRange> axes; - ArrayList<MotionRange> hats; + List<Integer> axes = new ArrayList<Integer>(); + protected boolean hasAxisHat = false; + /* + * Keep track of values so we can prevent flooding the engine with useless events. + */ + protected final SparseArray axesValues = new SparseArray<Float>(4); + protected int hatX; + protected int hatY; } diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle index 65b7bb9dc9..66077060ea 100644 --- a/platform/android/java/nativeSrcsConfigs/build.gradle +++ b/platform/android/java/nativeSrcsConfigs/build.gradle @@ -31,6 +31,8 @@ android { } } + ndkVersion versions.ndkVersion + externalNativeBuild { cmake { path "CMakeLists.txt" diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 604ad4e04b..91cecdd704 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -1351,6 +1351,8 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> Vector<String> added_embedded_dependenciy_names; HashMap<String, String> plist_values; + Set<String> plugin_linker_flags; + Error err; for (int i = 0; i < enabled_plugins.size(); i++) { @@ -1417,6 +1419,13 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> p_config_data.capabilities.push_back(capability); } + // Linker flags + // Checking duplicates + for (int j = 0; j < plugin.linker_flags.size(); j++) { + String linker_flag = plugin.linker_flags[j]; + plugin_linker_flags.insert(linker_flag); + } + // Plist // Using hash map container to remove duplicates const String *K = nullptr; @@ -1497,6 +1506,27 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset> p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_"); } + + // Update Linker Flag Values + { + String result_linker_flags = " "; + for (Set<String>::Element *E = plugin_linker_flags.front(); E; E = E->next()) { + const String &flag = E->get(); + + if (flag.length() == 0) { + continue; + } + + if (result_linker_flags.length() > 0) { + result_linker_flags += ' '; + } + + result_linker_flags += flag; + } + result_linker_flags = result_linker_flags.replace("\"", "\\\""); + p_config_data.linker_flags += result_linker_flags; + } + return OK; } diff --git a/platform/iphone/godot_app_delegate.h b/platform/iphone/godot_app_delegate.h index 76d8aa409f..6335ada50e 100644 --- a/platform/iphone/godot_app_delegate.h +++ b/platform/iphone/godot_app_delegate.h @@ -31,7 +31,6 @@ #import <UIKit/UIKit.h> typedef NSObject<UIApplicationDelegate> ApplicationDelegateService; -typedef void (^APNSNotification)(UIBackgroundFetchResult); @interface GodotApplicalitionDelegate : NSObject <UIApplicationDelegate> @@ -39,27 +38,4 @@ typedef void (^APNSNotification)(UIBackgroundFetchResult); + (void)addService:(ApplicationDelegateService *)service; -- (void)godot:(UIApplication *)application receivedNotificationToken:(NSData *)deviceToken; -- (void)godot:(UIApplication *)application receivedNotificationError:(NSError *)error; -- (void)godot:(UIApplication *)application receivedNotification:(NSDictionary *)userInfo completion:(APNSNotification)completionHandler; - @end - -#define GODOT_ENABLE_PUSH_NOTIFICATIONS \ - @interface GodotApplicalitionDelegate (PushNotifications) \ - @end \ - @implementation GodotApplicalitionDelegate (PushNotifications) \ - -(void)application : (UIApplication *)application \ - didRegisterForRemoteNotificationsWithDeviceToken : (NSData *)deviceToken { \ - [self godot:application receivedNotificationToken:deviceToken]; \ - } \ - -(void)application : (UIApplication *)application \ - didFailToRegisterForRemoteNotificationsWithError : (NSError *)error { \ - [self godot:application receivedNotificationError:error]; \ - } \ - -(void)application : (UIApplication *)application \ - didReceiveRemoteNotification : (NSDictionary *)userInfo \ - fetchCompletionHandler : (APNSNotification)completionHandler { \ - [self godot:application receivedNotification:userInfo completion:completionHandler]; \ - } \ - @end diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m index 9d298162f3..3ce9bffc79 100644 --- a/platform/iphone/godot_app_delegate.m +++ b/platform/iphone/godot_app_delegate.m @@ -302,37 +302,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil; // MARK: Remote Notification -- (void)godot:(UIApplication *)application receivedNotificationToken:(NSData *)deviceToken { - for (ApplicationDelegateService *service in services) { - if (![service respondsToSelector:_cmd]) { - continue; - } - - [service application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; - } -} - -- (void)godot:(UIApplication *)application receivedNotificationError:(NSError *)error { - for (ApplicationDelegateService *service in services) { - if (![service respondsToSelector:_cmd]) { - continue; - } - - [service application:application didFailToRegisterForRemoteNotificationsWithError:error]; - } -} - -- (void)godot:(UIApplication *)application receivedNotification:(NSDictionary *)userInfo completion:(APNSNotification)completionHandler { - for (ApplicationDelegateService *service in services) { - if (![service respondsToSelector:_cmd]) { - continue; - } - - [service application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; - } - - completionHandler(UIBackgroundFetchResultNoData); -} +// Moved to the iOS Plugin // MARK: User Activity and Handling Quick Actions diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h index 29960c47a8..265f826173 100644 --- a/platform/iphone/godot_view.h +++ b/platform/iphone/godot_view.h @@ -32,12 +32,20 @@ class String; +@class GodotView; @protocol DisplayLayer; @protocol GodotViewRendererProtocol; +@protocol GodotViewDelegate + +- (BOOL)godotViewFinishedSetup:(GodotView *)view; + +@end + @interface GodotView : UIView @property(assign, nonatomic) id<GodotViewRendererProtocol> renderer; +@property(assign, nonatomic) id<GodotViewDelegate> delegate; @property(assign, readonly, nonatomic) BOOL isActive; diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm index bf073ae295..887297848e 100644 --- a/platform/iphone/godot_view.mm +++ b/platform/iphone/godot_view.mm @@ -120,6 +120,7 @@ static const int max_touches = 8; [self stopRendering]; self.renderer = nil; + self.delegate = nil; if (self.renderingLayer) { [self.renderingLayer removeFromSuperlayer]; @@ -241,6 +242,14 @@ static const int max_touches = 8; return; } + if (self.delegate) { + BOOL delegateFinishedSetup = [self.delegate godotViewFinishedSetup:self]; + + if (!delegateFinishedSetup) { + return; + } + } + [self handleMotion]; [self.renderer renderOnView:self]; } diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm index 625cbf178e..51c4da2960 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/iphone/os_iphone.mm @@ -144,8 +144,6 @@ void OSIPhone::deinitialize_modules() { } void OSIPhone::set_main_loop(MainLoop *p_main_loop) { - godot_ios_plugins_initialize(); - main_loop = p_main_loop; if (main_loop) { @@ -179,6 +177,8 @@ bool OSIPhone::iterate() { } void OSIPhone::start() { + godot_ios_plugins_initialize(); + Main::start(); if (joypad_iphone) { diff --git a/platform/iphone/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h index 72fab13600..f4e30c8349 100644 --- a/platform/iphone/plugin/godot_plugin_config.h +++ b/platform/iphone/plugin/godot_plugin_config.h @@ -66,6 +66,7 @@ struct PluginConfigIOS { inline static const char *DEPENDENCIES_SYSTEM_KEY = "system"; inline static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities"; inline static const char *DEPENDENCIES_FILES_KEY = "files"; + inline static const char *DEPENDENCIES_LINKER_FLAGS = "linker_flags"; inline static const char *PLIST_SECTION = "plist"; @@ -89,6 +90,8 @@ struct PluginConfigIOS { Vector<String> files_to_copy; Vector<String> capabilities; + Vector<String> linker_flags; + // Optional plist section // Supports only string types for now HashMap<String, String> plist; @@ -260,6 +263,8 @@ static inline PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, co plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files); plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>()); + + plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>()); } if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) { diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index c41aa13bb7..6cef244567 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -40,12 +40,14 @@ #import <AVFoundation/AVFoundation.h> #import <GameController/GameController.h> -@interface ViewController () +@interface ViewController () <GodotViewDelegate> @property(strong, nonatomic) GodotViewRenderer *renderer; @property(strong, nonatomic) GodotNativeVideoView *videoView; @property(strong, nonatomic) GodotKeyboardInputView *keyboardView; +@property(strong, nonatomic) UIView *godotLoadingOverlay; + @end @implementation ViewController @@ -62,6 +64,7 @@ self.view = view; view.renderer = self.renderer; + view.delegate = self; } - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { @@ -97,6 +100,7 @@ [super viewDidLoad]; [self observeKeyboard]; + [self displayLoadingOverlay]; if (@available(iOS 11.0, *)) { [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; @@ -121,6 +125,31 @@ object:nil]; } +- (void)displayLoadingOverlay { + NSBundle *bundle = [NSBundle mainBundle]; + NSString *storyboardName = @"Launch Screen"; + + if ([bundle pathForResource:storyboardName ofType:@"storyboardc"] == nil) { + return; + } + + UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle]; + + UIViewController *controller = [launchStoryboard instantiateInitialViewController]; + self.godotLoadingOverlay = controller.view; + self.godotLoadingOverlay.frame = self.view.bounds; + self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + + [self.view addSubview:self.godotLoadingOverlay]; +} + +- (BOOL)godotViewFinishedSetup:(GodotView *)view { + [self.godotLoadingOverlay removeFromSuperview]; + self.godotLoadingOverlay = nil; + + return YES; +} + - (void)dealloc { [self.videoView stopVideo]; @@ -130,6 +159,11 @@ self.renderer = nil; + if (self.godotLoadingOverlay) { + [self.godotLoadingOverlay removeFromSuperview]; + self.godotLoadingOverlay = nil; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; } diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 915e8eeacf..5e2dddd8e7 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -93,7 +93,7 @@ EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, co DisplayServerJavaScript *display = get_singleton(); // Empty ID is canvas. String target_id = String::utf8(p_event->id); - if (target_id.is_empty() || target_id == String::utf8(display->canvas_id)) { + if (target_id.is_empty() || target_id == String::utf8(&(display->canvas_id[1]))) { // This event property is the only reliable data on // browser fullscreen state. if (p_event->isFullscreen) { @@ -455,7 +455,7 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const { EmscriptenPointerlockChangeEvent ev; emscripten_get_pointerlock_status(&ev); - return (ev.isActive && String::utf8(ev.id) == String::utf8(canvas_id)) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; + return (ev.isActive && String::utf8(ev.id) == String::utf8(&canvas_id[1])) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; } // Wheel @@ -703,6 +703,9 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive // Ensure the canvas ID. godot_js_config_canvas_id_get(canvas_id, 256); + // Handle contextmenu, webglcontextlost + godot_js_display_setup_canvas(); + // Check if it's windows. swap_cancel_ok = godot_js_display_is_swap_ok_cancel() == 1; @@ -842,7 +845,8 @@ Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const { EmscriptenFullscreenChangeEvent ev; EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev); ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i()); - return Size2i(ev.screenWidth, ev.screenHeight); + double scale = godot_js_display_pixel_ratio_get(); + return Size2i(ev.screenWidth * scale, ev.screenHeight * scale); } Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const { @@ -852,7 +856,11 @@ Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const { } int DisplayServerJavaScript::screen_get_dpi(int p_screen) const { - return 96; // TODO maybe check pixel ratio via window.devicePixelRatio * 96? Inexact. + return godot_js_display_screen_dpi_get(); +} + +float DisplayServerJavaScript::screen_get_scale(int p_screen) const { + return godot_js_display_pixel_ratio_get(); } Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const { diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index e28fbc56f3..e2fe731abf 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -136,6 +136,7 @@ public: Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; // windows Vector<DisplayServer::WindowID> get_window_list() const override; diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h index 0006848756..d2a2fbd6db 100644 --- a/platform/javascript/godot_js.h +++ b/platform/javascript/godot_js.h @@ -51,6 +51,7 @@ extern int godot_js_os_execute(const char *p_json); extern void godot_js_os_shell_open(const char *p_uri); // Display +extern int godot_js_display_screen_dpi_get(); extern double godot_js_display_pixel_ratio_get(); extern void godot_js_display_alert(const char *p_text); extern int godot_js_display_touchscreen_is_available(); @@ -86,6 +87,7 @@ extern int godot_js_display_gamepad_sample_get(int p_idx, float r_btns[16], int3 extern void godot_js_display_notification_cb(void (*p_callback)(int p_notification), int p_enter, int p_exit, int p_in, int p_out); extern void godot_js_display_paste_cb(void (*p_callback)(const char *p_text)); extern void godot_js_display_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec)); +extern void godot_js_display_setup_canvas(); #ifdef __cplusplus } #endif diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index c8c48dd582..1136ea299d 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -104,7 +104,11 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector Error err = prepare_request(p_method, p_url, p_headers); if (err != OK) return err; - godot_xhr_send_data(xhr_id, p_body.ptr(), p_body.size()); + if (p_body.is_empty()) { + godot_xhr_send(xhr_id, nullptr, 0); + } else { + godot_xhr_send(xhr_id, p_body.ptr(), p_body.size()); + } return OK; } @@ -112,7 +116,12 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str Error err = prepare_request(p_method, p_url, p_headers); if (err != OK) return err; - godot_xhr_send_string(xhr_id, p_body.utf8().get_data()); + if (p_body.is_empty()) { + godot_xhr_send(xhr_id, nullptr, 0); + } else { + const CharString cs = p_body.utf8(); + godot_xhr_send(xhr_id, cs.get_data(), cs.length()); + } return OK; } diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h index d32b2f265e..a9d6faade2 100644 --- a/platform/javascript/http_request.h +++ b/platform/javascript/http_request.h @@ -53,9 +53,7 @@ extern int godot_xhr_open(int p_xhr_id, const char *p_method, const char *p_url, extern void godot_xhr_set_request_header(int p_xhr_id, const char *p_header, const char *p_value); -extern void godot_xhr_send_null(int p_xhr_id); -extern void godot_xhr_send_string(int p_xhr_id, const char *p_data); -extern void godot_xhr_send_data(int p_xhr_id, const void *p_data, int p_len); +extern void godot_xhr_send(int p_xhr_id, const void *p_data, int p_len); extern void godot_xhr_abort(int p_xhr_id); /* this is an HTTPClient::ResponseCode, not ::Status */ diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 0b8af70b13..0fe95b0a8f 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -88,6 +88,13 @@ extern EMSCRIPTEN_KEEPALIVE int godot_js_main(int argc, char *argv[]) { Main::start(); os->get_main_loop()->initialize(); +#ifdef TOOLS_ENABLED + if (Main::is_project_manager() && FileAccess::exists("/tmp/preload.zip")) { + PackedStringArray ps; + ps.push_back("/tmp/preload.zip"); + os->get_main_loop()->emit_signal("files_dropped", ps, -1); + } +#endif emscripten_set_main_loop(main_loop_callback, -1, false); // Immediately run the first iteration. // We are inside an animation frame, we want to immediately draw on the newly setup canvas. diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js index 01232cbece..321221323c 100644 --- a/platform/javascript/js/engine/engine.js +++ b/platform/javascript/js/engine/engine.js @@ -107,17 +107,6 @@ const Engine = (function () { me.canvas.tabIndex = 0; } - // Disable right-click context menu. - me.canvas.addEventListener('contextmenu', function (ev) { - ev.preventDefault(); - }, false); - - // Until context restoration is implemented warn the user of context loss. - me.canvas.addEventListener('webglcontextlost', function (ev) { - alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert - ev.preventDefault(); - }, false); - // Browser locale, or custom one if defined. let locale = me.customLocale; if (!locale) { diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js index 2977b7c122..9ec295b39f 100644 --- a/platform/javascript/js/libs/library_godot_display.js +++ b/platform/javascript/js/libs/library_godot_display.js @@ -405,6 +405,27 @@ const GodotDisplay = { $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads'], $GodotDisplay: { window_icon: '', + findDPI: function () { + function testDPI(dpi) { + return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches; + } + function bisect(low, high, func) { + const mid = parseInt(((high - low) / 2) + low, 10); + if (high - low <= 1) { + return func(high) ? high : low; + } + if (func(mid)) { + return bisect(low, mid, func); + } + return bisect(mid, high, func); + } + try { + const dpi = bisect(0, 800, testDPI); + return dpi >= 96 ? dpi : 96; + } catch (e) { + return 96; + } + }, }, godot_js_display_is_swap_ok_cancel__sig: 'i', @@ -422,6 +443,11 @@ const GodotDisplay = { window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert }, + godot_js_display_screen_dpi_get__sig: 'i', + godot_js_display_screen_dpi_get: function () { + return GodotDisplay.findDPI(); + }, + godot_js_display_pixel_ratio_get__sig: 'f', godot_js_display_pixel_ratio_get: function () { return window.devicePixelRatio || 1; @@ -619,6 +645,18 @@ const GodotDisplay = { GodotDisplayListeners.add(canvas, 'drop', GodotDisplayDragDrop.handler(dropFiles)); }, + godot_js_display_setup_canvas__sig: 'v', + godot_js_display_setup_canvas: function () { + const canvas = GodotConfig.canvas; + GodotDisplayListeners.add(canvas, 'contextmenu', function (ev) { + ev.preventDefault(); + }, false); + GodotDisplayListeners.add(canvas, 'webglcontextlost', function (ev) { + alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert + ev.preventDefault(); + }, false); + }, + /* * Gamepads */ diff --git a/platform/javascript/js/libs/library_godot_http_request.js b/platform/javascript/js/libs/library_godot_http_request.js index 930d3209f8..7dc2a2df29 100644 --- a/platform/javascript/js/libs/library_godot_http_request.js +++ b/platform/javascript/js/libs/library_godot_http_request.js @@ -82,31 +82,13 @@ const GodotHTTPRequest = { GodotHTTPRequest.requests[xhrId].setRequestHeader(GodotRuntime.parseString(header), GodotRuntime.parseString(value)); }, - godot_xhr_send_null__sig: 'vi', - godot_xhr_send_null: function (xhrId) { - GodotHTTPRequest.requests[xhrId].send(); - }, - - godot_xhr_send_string__sig: 'vii', - godot_xhr_send_string: function (xhrId, strPtr) { - if (!strPtr) { - GodotRuntime.error('Failed to send string per XHR: null pointer'); - return; - } - GodotHTTPRequest.requests[xhrId].send(GodotRuntime.parseString(strPtr)); - }, - - godot_xhr_send_data__sig: 'viii', - godot_xhr_send_data: function (xhrId, ptr, len) { - if (!ptr) { - GodotRuntime.error('Failed to send data per XHR: null pointer'); - return; - } - if (len < 0) { - GodotRuntime.error('Failed to send data per XHR: buffer length less than 0'); - return; + godot_xhr_send__sig: 'viii', + godot_xhr_send: function (xhrId, p_ptr, p_len) { + let data = null; + if (p_ptr && p_len) { + data = GodotRuntime.heapCopy(HEAP8, p_ptr, p_len); } - GodotHTTPRequest.requests[xhrId].send(HEAPU8.subarray(ptr, ptr + len)); + GodotHTTPRequest.requests[xhrId].send(data); }, godot_xhr_abort__sig: 'vi', diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index 6e43ffcedb..ddc698a55b 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -18,5 +18,5 @@ common_x11 = [ prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_x11) -if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: +if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd)) diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index a819731328..13d1fe3237 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -64,15 +64,15 @@ def get_opts(): BoolVariable("use_llvm", "Use the LLVM compiler", False), BoolVariable("use_lld", "Use the LLD linker", False), BoolVariable("use_thinlto", "Use ThinLTO", False), - BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False), + BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True), BoolVariable("use_coverage", "Test Godot coverage", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False), BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False), BoolVariable("pulseaudio", "Detect and use PulseAudio", True), - BoolVariable("udev", "Use udev for gamepad connection callbacks", False), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("udev", "Use udev for gamepad connection callbacks", True), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("touch", "Enable touch events", True), BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), @@ -92,7 +92,7 @@ def configure(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -102,7 +102,7 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": @@ -390,4 +390,7 @@ def configure(env): # Link those statically for portability if env["use_static_cpp"]: - env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) + # Workaround for GH-31743, Ubuntu 18.04 i386 crashes when it's used. + # That doesn't make any sense but it's likely a Ubuntu bug? + if is64 or env["bits"] == "64": + env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) diff --git a/platform/osx/SCsub b/platform/osx/SCsub index aa95a89444..46c13d8550 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -18,5 +18,5 @@ files = [ prog = env.add_program("#bin/godot", files) -if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: +if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_osx_builders.make_debug_osx)) diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 466f68d269..acea00c5ac 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -31,7 +31,7 @@ def get_opts(): False, ), EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), @@ -54,7 +54,7 @@ def configure(env): if env["arch"] != "arm64": env.Prepend(CCFLAGS=["-msse2"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -63,7 +63,7 @@ def configure(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": diff --git a/platform/server/detect.py b/platform/server/detect.py index db503584d3..1c3fa990fe 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -32,13 +32,13 @@ def get_opts(): return [ BoolVariable("use_llvm", "Use the LLVM compiler", False), - BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False), + BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True), BoolVariable("use_coverage", "Test Godot coverage", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False), BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False), BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False), ] @@ -58,7 +58,7 @@ def configure(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": @@ -68,7 +68,7 @@ def configure(env): env.Prepend(CCFLAGS=["-Os"]) env.Prepend(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "debug": diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 8b60e55d2d..fa97948395 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -44,7 +44,6 @@ #include "platform/windows/windows_terminal_logger.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_default.h" -#include "servers/rendering/rendering_server_wrap_mt.h" #include <ppltasks.h> #include <wrl.h> diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 0c9aa77803..47d8e14680 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -32,5 +32,5 @@ if env["vsproj"]: env.vs_srcs += ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): - if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]: + if env["debug_symbols"] and env["separate_debug_symbols"]: env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw)) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 5216fca2ca..f26dea8d35 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -64,7 +64,7 @@ def get_opts(): # XP support dropped after EOL due to missing API for IPv6 and other issues # Vista support dropped after EOL due to GH-10243 ("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"), - EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")), + BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), EnumVariable("windows_subsystem", "Windows subsystem", "default", ("default", "console", "gui")), BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False), ("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None), @@ -204,12 +204,12 @@ def configure_msvc(env, manual_msvc_config): env.Append(LINKFLAGS=["/OPT:REF"]) elif env["target"] == "debug": - env.AppendUnique(CCFLAGS=["/Z7", "/Od", "/EHsc"]) + env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"]) env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"]) env.Append(LINKFLAGS=["/DEBUG"]) - if env["debug_symbols"] == "yes": - env.AppendUnique(CCFLAGS=["/Z7"]) + if env["debug_symbols"]: + env.AppendUnique(CCFLAGS=["/Zi", "/FS"]) env.AppendUnique(LINKFLAGS=["/DEBUG"]) if env["windows_subsystem"] == "gui": @@ -224,6 +224,7 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CCFLAGS=["/MT"]) else: env.AppendUnique(CCFLAGS=["/MD"]) + env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"]) # Force to use Unicode encoding env.AppendUnique(CCFLAGS=["/utf-8"]) @@ -339,13 +340,13 @@ def configure_mingw(env): else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) elif env["target"] == "release_debug": env.Append(CCFLAGS=["-O2"]) env.Append(CPPDEFINES=["DEBUG_ENABLED"]) - if env["debug_symbols"] == "yes": + if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) if env["optimize"] == "speed": # optimize for speed (default) env.Append(CCFLAGS=["-O2"]) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 14e7d395d3..21dfc4ae2c 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1784,7 +1784,10 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) Ref<InputEventFromWindow> event_from_window = p_event; if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { //send to a window - ERR_FAIL_COND(!windows.has(event_from_window->get_window_id())); + if (!windows.has(event_from_window->get_window_id())) { + in_dispatch_input_event = false; + ERR_FAIL_MSG("DisplayServerWindows: Invalid window id in input event."); + } Callable callable = windows[event_from_window->get_window_id()].input_event_callback; if (callable.is_null()) { in_dispatch_input_event = false; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index fe007027da..2dd9ed4bd1 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -45,7 +45,6 @@ #include "platform/windows/display_server_windows.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_default.h" -#include "servers/rendering/rendering_server_wrap_mt.h" #include "windows_terminal_logger.h" #include <avrt.h> diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index d9d551074d..f39850441b 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -409,7 +409,7 @@ void AnimatedSprite2D::_notification(int p_what) { } update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -477,7 +477,7 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { set_frame(frame); } - _change_notify(); + notify_property_list_changed(); _reset_timeout(); update(); update_configuration_warning(); @@ -510,7 +510,7 @@ void AnimatedSprite2D::set_frame(int p_frame) { frame = p_frame; _reset_timeout(); update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -546,7 +546,6 @@ void AnimatedSprite2D::set_offset(const Point2 &p_offset) { offset = p_offset; update(); item_rect_changed(); - _change_notify("offset"); } Point2 AnimatedSprite2D::get_offset() const { @@ -573,8 +572,7 @@ bool AnimatedSprite2D::is_flipped_v() const { void AnimatedSprite2D::_res_changed() { set_frame(frame); - _change_notify("frame"); - _change_notify("animation"); + update(); } @@ -642,7 +640,7 @@ void AnimatedSprite2D::set_animation(const StringName &p_animation) { animation = p_animation; _reset_timeout(); set_frame(0); - _change_notify(); + notify_property_list_changed(); update(); } @@ -712,15 +710,4 @@ void AnimatedSprite2D::_bind_methods() { } AnimatedSprite2D::AnimatedSprite2D() { - centered = true; - hflip = false; - vflip = false; - - frame = 0; - speed_scale = 1.0f; - playing = false; - backwards = false; - animation = "default"; - timeout = 0; - is_over = false; } diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index a558a3e657..5e53a401e2 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -38,14 +38,9 @@ class SpriteFrames : public Resource { GDCLASS(SpriteFrames, Resource); struct Anim { - float speed; - bool loop; + float speed = 5.0; + bool loop = true; Vector<Ref<Texture2D>> frames; - - Anim() { - loop = true; - speed = 5; - } }; Map<StringName, Anim> animations; @@ -109,20 +104,20 @@ class AnimatedSprite2D : public Node2D { GDCLASS(AnimatedSprite2D, Node2D); Ref<SpriteFrames> frames; - bool playing; - bool backwards; - StringName animation; - int frame; - float speed_scale; + bool playing = false; + bool backwards = false; + StringName animation = "default"; + int frame = 0; + float speed_scale = 1.0f; - bool centered; + bool centered = true; Point2 offset; - bool is_over; - float timeout; + bool is_over = false; + float timeout = 0.0; - bool hflip; - bool vflip; + bool hflip = false; + bool vflip = false; void _res_changed(); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index fae893a76c..68d5b4b540 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -627,20 +627,8 @@ void Area2D::_bind_methods() { Area2D::Area2D() : CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) { - space_override = SPACE_OVERRIDE_DISABLED; set_gravity(98); set_gravity_vector(Vector2(0, 1)); - gravity_is_point = false; - gravity_distance_scale = 0; - linear_damp = 0.1; - angular_damp = 1; - locked = false; - priority = 0; - monitoring = false; - monitorable = false; - collision_mask = 1; - collision_layer = 1; - audio_bus_override = false; set_monitoring(true); set_monitorable(true); } diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 0b45675555..39b022fd2c 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -47,19 +47,19 @@ public: }; private: - SpaceOverride space_override; + SpaceOverride space_override = SPACE_OVERRIDE_DISABLED; Vector2 gravity_vec; real_t gravity; - bool gravity_is_point; - real_t gravity_distance_scale; - real_t linear_damp; - real_t angular_damp; - uint32_t collision_mask; - uint32_t collision_layer; - int priority; - bool monitoring; - bool monitorable; - bool locked; + bool gravity_is_point = false; + real_t gravity_distance_scale = 0.0; + real_t linear_damp = 0.1; + real_t angular_damp = 1.0; + uint32_t collision_mask = 1; + uint32_t collision_layer = 1; + int priority = 0; + bool monitoring = false; + bool monitorable = false; + bool locked = false; void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); @@ -67,8 +67,8 @@ private: void _body_exit_tree(ObjectID p_id); struct ShapePair { - int body_shape; - int area_shape; + int body_shape = 0; + int area_shape = 0; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return area_shape < p_sp.area_shape; @@ -85,8 +85,8 @@ private: }; struct BodyState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<ShapePair> shapes; }; @@ -98,8 +98,8 @@ private: void _area_exit_tree(ObjectID p_id); struct AreaShapePair { - int area_shape; - int self_shape; + int area_shape = 0; + int self_shape = 0; bool operator<(const AreaShapePair &p_sp) const { if (area_shape == p_sp.area_shape) { return self_shape < p_sp.self_shape; @@ -116,15 +116,15 @@ private: }; struct AreaState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<AreaShapePair> shapes; }; Map<ObjectID, AreaState> area_map; void _clear_monitoring(); - bool audio_bus_override; + bool audio_bus_override = false; StringName audio_bus; protected: diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index f1eb7d017d..4e7eec906c 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -249,15 +249,11 @@ void AudioStreamPlayer2D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - //do not update, this makes it easier to animate (will shut off otherwise) - //_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_physics_process_internal(false); - //do not update, this makes it easier to animate (will shut off otherwise) - //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -404,7 +400,7 @@ void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer2D::_bus_layout_changed() { - _change_notify(); + notify_property_list_changed(); } void AudioStreamPlayer2D::set_max_distance(float p_pixels) { @@ -503,21 +499,6 @@ void AudioStreamPlayer2D::_bind_methods() { } AudioStreamPlayer2D::AudioStreamPlayer2D() { - volume_db = 0; - pitch_scale = 1.0; - autoplay = false; - setseek = -1; - active = false; - output_count = 0; - prev_output_count = 0; - max_distance = 2000; - attenuation = 1; - setplay = -1; - output_ready = false; - area_mask = 1; - stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed)); } diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 4eb709facb..6fb8cc414c 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -47,32 +47,32 @@ private: struct Output { AudioFrame vol; - int bus_index; - Viewport *viewport; //pointer only used for reference to previous mix + int bus_index = 0; + Viewport *viewport = nullptr; //pointer only used for reference to previous mix }; Output outputs[MAX_OUTPUTS]; - volatile int output_count; - volatile bool output_ready; + volatile int output_count = 0; + volatile bool output_ready = false; //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks) Output prev_outputs[MAX_OUTPUTS]; - int prev_output_count; + int prev_output_count = 0; Ref<AudioStreamPlayback> stream_playback; Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; - volatile float setseek; - volatile bool active; - volatile float setplay; + volatile float setseek = -1.0; + volatile bool active = false; + volatile float setplay = -1.0; - float volume_db; - float pitch_scale; - bool autoplay; - bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + float volume_db = 0.0; + float pitch_scale = 1.0; + bool autoplay = false; + bool stream_paused = false; + bool stream_paused_fade_in = false; + bool stream_paused_fade_out = false; StringName bus; void _mix_audio(); @@ -83,10 +83,10 @@ private: void _bus_layout_changed(); - uint32_t area_mask; + uint32_t area_mask = 1; - float max_distance; - float attenuation; + float max_distance = 2000.0; + float attenuation = 1.0; protected: void _validate_property(PropertyInfo &property) const override; diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 91c887cb84..539a66b881 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -93,8 +93,6 @@ void BackBufferCopy::_bind_methods() { } BackBufferCopy::BackBufferCopy() { - rect = Rect2(-100, -100, 200, 200); - copy_mode = COPY_MODE_RECT; _update_copy_mode(); } diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 0916d344f9..6bdb3aaab2 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -44,8 +44,8 @@ public: }; private: - Rect2 rect; - CopyMode copy_mode; + Rect2 rect = Rect2(-100, -100, 200, 200); + CopyMode copy_mode = COPY_MODE_RECT; void _update_copy_mode(); diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 4f45325d3a..853e92780b 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -749,9 +749,6 @@ void Camera2D::_bind_methods() { } Camera2D::Camera2D() { - anchor_mode = ANCHOR_MODE_DRAG_CENTER; - rotating = false; - current = false; limit[SIDE_LEFT] = -10000000; limit[SIDE_TOP] = -10000000; limit[SIDE_RIGHT] = 10000000; @@ -761,27 +758,6 @@ Camera2D::Camera2D() { drag_margin[SIDE_TOP] = 0.2; drag_margin[SIDE_RIGHT] = 0.2; drag_margin[SIDE_BOTTOM] = 0.2; - camera_pos = Vector2(); - first = true; - smoothing_enabled = false; - limit_smoothing_enabled = false; - custom_viewport = nullptr; - - process_mode = CAMERA2D_PROCESS_IDLE; - - smoothing = 5.0; - zoom = Vector2(1, 1); - - screen_drawing_enabled = true; - limit_drawing_enabled = false; - margin_drawing_enabled = false; - - drag_horizontal_enabled = false; - drag_vertical_enabled = false; - drag_horizontal_offset = 0; - drag_vertical_offset = 0; - drag_horizontal_offset_changed = false; - drag_vertical_offset_changed = false; set_notify_transform(true); } diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 8977d872f0..3a7d01901d 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -51,32 +51,32 @@ public: protected: Point2 camera_pos; Point2 smoothed_camera_pos; - bool first; + bool first = true; ObjectID custom_viewport_id; // to check validity - Viewport *custom_viewport; - Viewport *viewport; + Viewport *custom_viewport = nullptr; + Viewport *viewport = nullptr; StringName group_name; StringName canvas_group_name; RID canvas; Vector2 offset; - Vector2 zoom; - AnchorMode anchor_mode; - bool rotating; - bool current; - float smoothing; - bool smoothing_enabled; + Vector2 zoom = Vector2(1, 1); + AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER; + bool rotating = false; + bool current = false; + float smoothing = 5.0; + bool smoothing_enabled = false; int limit[4]; - bool limit_smoothing_enabled; + bool limit_smoothing_enabled = false; float drag_margin[4]; - bool drag_horizontal_enabled; - bool drag_vertical_enabled; - float drag_horizontal_offset; - float drag_vertical_offset; - bool drag_horizontal_offset_changed; - bool drag_vertical_offset_changed; + bool drag_horizontal_enabled = false; + bool drag_vertical_enabled = false; + float drag_horizontal_offset = 0.0; + float drag_vertical_offset = 0.0; + bool drag_horizontal_offset_changed = false; + bool drag_vertical_offset_changed = false; Point2 camera_screen_center; void _update_process_mode(); @@ -87,11 +87,11 @@ protected: void _set_old_smoothing(float p_enable); - bool screen_drawing_enabled; - bool limit_drawing_enabled; - bool margin_drawing_enabled; + bool screen_drawing_enabled = true; + bool limit_drawing_enabled = false; + bool margin_drawing_enabled = false; - Camera2DProcessMode process_mode; + Camera2DProcessMode process_mode = CAMERA2D_PROCESS_IDLE; Size2 _get_camera_screen_size() const; diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp index 6e90afde21..5d5aaae505 100644 --- a/scene/2d/canvas_modulate.cpp +++ b/scene/2d/canvas_modulate.cpp @@ -94,7 +94,6 @@ String CanvasModulate::get_configuration_warning() const { } CanvasModulate::CanvasModulate() { - color = Color(1, 1, 1, 1); } CanvasModulate::~CanvasModulate() { diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index 6efc0cab9b..4d55a5d9cb 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -36,7 +36,7 @@ class CanvasModulate : public Node2D { GDCLASS(CanvasModulate, Node2D); - Color color; + Color color = Color(1, 1, 1, 1); protected: void _notification(int p_what); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index f0b007f843..c83ed36917 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -165,7 +165,7 @@ bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owne return shapes[p_owner].one_way_collision; } -void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin) { +void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin) { if (area) { return; //not for areas } @@ -179,7 +179,7 @@ void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owne } } -float CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const { +real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const { ERR_FAIL_COND_V(!shapes.has(p_owner), 0); return shapes[p_owner].one_way_collision_margin; diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index a2112c27f4..e82b61d441 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -37,35 +37,29 @@ class CollisionObject2D : public Node2D { GDCLASS(CollisionObject2D, Node2D); - bool area; + bool area = false; RID rid; - bool pickable; + bool pickable = false; struct ShapeData { - Object *owner; + Object *owner = nullptr; Transform2D xform; struct Shape { Ref<Shape2D> shape; - int index; + int index = 0; }; Vector<Shape> shapes; - bool disabled; - bool one_way_collision; - float one_way_collision_margin; - - ShapeData() { - disabled = false; - one_way_collision = false; - one_way_collision_margin = 0; - owner = nullptr; - } + + bool disabled = false; + bool one_way_collision = false; + real_t one_way_collision_margin = 0.0; }; - int total_subshapes; + int total_subshapes = 0; Map<uint32_t, ShapeData> shapes; - bool only_update_transform_changes; //this is used for sync physics in KinematicBody + bool only_update_transform_changes = false; //this is used for sync physics in KinematicBody protected: CollisionObject2D(RID p_rid, bool p_area); @@ -97,8 +91,8 @@ public: void shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable); bool is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const; - void shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin); - float get_shape_owner_one_way_collision_margin(uint32_t p_owner) const; + void shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin); + real_t get_shape_owner_one_way_collision_margin(uint32_t p_owner) const; void shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape); int shape_owner_get_shape_count(uint32_t p_owner) const; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 851e40cda6..39d7705226 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -158,7 +158,7 @@ void CollisionPolygon2D::_notification(int p_what) { Vector2 line_to(0, 20); draw_line(Vector2(), line_to, dcol, 3); Vector<Vector2> pts; - float tsize = 8; + real_t tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); @@ -275,14 +275,14 @@ bool CollisionPolygon2D::is_one_way_collision_enabled() const { return one_way_collision; } -void CollisionPolygon2D::set_one_way_collision_margin(float p_margin) { +void CollisionPolygon2D::set_one_way_collision_margin(real_t p_margin) { one_way_collision_margin = p_margin; if (parent) { parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } } -float CollisionPolygon2D::get_one_way_collision_margin() const { +real_t CollisionPolygon2D::get_one_way_collision_margin() const { return one_way_collision_margin; } @@ -310,12 +310,5 @@ void CollisionPolygon2D::_bind_methods() { } CollisionPolygon2D::CollisionPolygon2D() { - aabb = Rect2(-10, -10, 20, 20); - build_mode = BUILD_SOLIDS; set_notify_local_transform(true); - parent = nullptr; - owner_id = 0; - disabled = false; - one_way_collision = false; - one_way_collision_margin = 1.0; } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index caa5b2c3ec..9df9802629 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -46,14 +46,14 @@ public: }; protected: - Rect2 aabb; - BuildMode build_mode; + Rect2 aabb = Rect2(-10, -10, 20, 20); + BuildMode build_mode = BUILD_SOLIDS; Vector<Point2> polygon; - uint32_t owner_id; - CollisionObject2D *parent; - bool disabled; - bool one_way_collision; - float one_way_collision_margin; + uint32_t owner_id = 0; + CollisionObject2D *parent = nullptr; + bool disabled = false; + bool one_way_collision = false; + real_t one_way_collision_margin = 1.0; Vector<Vector<Vector2>> _decompose_in_convex(); @@ -86,8 +86,8 @@ public: void set_one_way_collision(bool p_enable); bool is_one_way_collision_enabled() const; - void set_one_way_collision_margin(float p_margin); - float get_one_way_collision_margin() const; + void set_one_way_collision_margin(real_t p_margin); + real_t get_one_way_collision_margin() const; CollisionPolygon2D(); }; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 37bed577ac..4d1d274542 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -125,7 +125,7 @@ void CollisionShape2D::_notification(int p_what) { Vector2 line_to(0, 20); draw_line(Vector2(), line_to, draw_col, 2); Vector<Vector2> pts; - float tsize = 8; + real_t tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0))); pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0))); @@ -215,14 +215,14 @@ bool CollisionShape2D::is_one_way_collision_enabled() const { return one_way_collision; } -void CollisionShape2D::set_one_way_collision_margin(float p_margin) { +void CollisionShape2D::set_one_way_collision_margin(real_t p_margin) { one_way_collision_margin = p_margin; if (parent) { parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin); } } -float CollisionShape2D::get_one_way_collision_margin() const { +real_t CollisionShape2D::get_one_way_collision_margin() const { return one_way_collision_margin; } @@ -243,11 +243,5 @@ void CollisionShape2D::_bind_methods() { } CollisionShape2D::CollisionShape2D() { - rect = Rect2(-Point2(10, 10), Point2(20, 20)); set_notify_local_transform(true); - owner_id = 0; - parent = nullptr; - disabled = false; - one_way_collision = false; - one_way_collision_margin = 1.0; } diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index 8a4d885393..695d0c6657 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -39,13 +39,13 @@ class CollisionObject2D; class CollisionShape2D : public Node2D { GDCLASS(CollisionShape2D, Node2D); Ref<Shape2D> shape; - Rect2 rect; - uint32_t owner_id; - CollisionObject2D *parent; + Rect2 rect = Rect2(-Point2(10, 10), Point2(20, 20)); + uint32_t owner_id = 0; + CollisionObject2D *parent = nullptr; void _shape_changed(); - bool disabled; - bool one_way_collision; - float one_way_collision_margin; + bool disabled = false; + bool one_way_collision = false; + real_t one_way_collision_margin = 1.0; void _update_in_shape_owner(bool p_xform_only = false); @@ -69,8 +69,8 @@ public: void set_one_way_collision(bool p_enable); bool is_one_way_collision_enabled() const; - void set_one_way_collision_margin(float p_margin); - float get_one_way_collision_margin() const; + void set_one_way_collision_margin(real_t p_margin); + real_t get_one_way_collision_margin() const; virtual String get_configuration_warning() const override; diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 7c9bd118d8..0e51264171 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -60,7 +60,7 @@ void CPUParticles2D::set_amount(int p_amount) { } particle_data.resize((8 + 4 + 4) * p_amount); - RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true); + RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true); particle_order.resize(p_amount); } @@ -410,7 +410,7 @@ bool CPUParticles2D::get_particle_flag(ParticleFlags p_particle_flag) const { void CPUParticles2D::set_emission_shape(EmissionShape p_shape) { ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; - _change_notify(); + notify_property_list_changed(); } void CPUParticles2D::set_emission_sphere_radius(float p_radius) { @@ -599,7 +599,7 @@ void CPUParticles2D::_particles_process(float p_delta) { cycle++; if (one_shot && cycle > 0) { set_emitting(false); - _change_notify(); + notify_property_list_changed(); } } @@ -671,6 +671,8 @@ void CPUParticles2D::_particles_process(float p_delta) { restart = true; } + float tv = 0.0; + if (restart) { if (!emitting) { p.active = false; @@ -685,12 +687,12 @@ void CPUParticles2D::_particles_process(float p_delta) { float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv); } p.seed = Math::rand(); @@ -700,7 +702,7 @@ void CPUParticles2D::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad)); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); @@ -721,7 +723,7 @@ void CPUParticles2D::_particles_process(float p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { - float s = Math::randf(), t = 2.0 * Math_PI * Math::randf(); + float s = Math::randf(), t = Math_TAU * Math::randf(); float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius; } break; @@ -765,59 +767,61 @@ void CPUParticles2D::_particles_process(float p_delta) { continue; } else if (p.time > p.lifetime) { p.active = false; + tv = 1.0; } else { uint32_t alt_seed = p.seed; p.time += local_delta; p.custom[1] = p.time / lifetime; + tv = p.time / p.lifetime; float tex_linear_velocity = 0.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]); + tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv); } float tex_orbit_velocity = 0.0; if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]); + tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv); } float tex_angular_velocity = 0.0; if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { - tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]); + tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv); } float tex_linear_accel = 0.0; if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) { - tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]); + tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv); } float tex_tangential_accel = 0.0; if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { - tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]); + tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv); } float tex_radial_accel = 0.0; if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) { - tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]); + tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv); } float tex_damping = 0.0; if (curve_parameters[PARAM_DAMPING].is_valid()) { - tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]); + tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv); } float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_speed = 0.0; if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) { - tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]); + tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]); + tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv); } Vector2 force = gravity; @@ -837,7 +841,7 @@ void CPUParticles2D::_particles_process(float p_delta) { //orbit velocity float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); if (orbit_amount != 0.0) { - float ang = orbit_amount * local_delta * Math_PI * 2.0; + float ang = orbit_amount * local_delta * Math_TAU; // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); @@ -869,15 +873,15 @@ void CPUParticles2D::_particles_process(float p_delta) { float tex_scale = 1.0; if (curve_parameters[PARAM_SCALE].is_valid()) { - tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]); + tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv); } float tex_hue_variation = 0.0; if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) { - tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]); + tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv); } - float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); + float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); float hue_rot_c = Math::cos(hue_rot_angle); float hue_rot_s = Math::sin(hue_rot_angle); @@ -893,7 +897,7 @@ void CPUParticles2D::_particles_process(float p_delta) { } if (color_ramp.is_valid()) { - p.color = color_ramp->get_color_at_offset(p.custom[1]) * color; + p.color = color_ramp->get_color_at_offset(tv) * color; } else { p.color = color; } @@ -1365,34 +1369,14 @@ void CPUParticles2D::_bind_methods() { } CPUParticles2D::CPUParticles2D() { - time = 0; - inactive_time = 0; - frame_remainder = 0; - cycle = 0; - redraw = false; - emitting = false; - mesh = RenderingServer::get_singleton()->mesh_create(); multimesh = RenderingServer::get_singleton()->multimesh_create(); RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, mesh); set_emitting(true); - set_one_shot(false); set_amount(8); - set_lifetime(1); - set_fixed_fps(0); - set_fractional_delta(true); - set_pre_process_time(0); - set_explosiveness_ratio(0); - set_randomness_ratio(0); - set_lifetime_randomness(0); set_use_local_coordinates(true); - set_draw_order(DRAW_ORDER_INDEX); - set_speed_scale(1); - - set_direction(Vector2(1, 0)); - set_spread(45); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); set_param(PARAM_ANGULAR_VELOCITY, 0); set_param(PARAM_ORBIT_VELOCITY, 0); @@ -1405,11 +1389,6 @@ CPUParticles2D::CPUParticles2D() { set_param(PARAM_HUE_VARIATION, 0); set_param(PARAM_ANIM_SPEED, 0); set_param(PARAM_ANIM_OFFSET, 0); - set_emission_shape(EMISSION_SHAPE_POINT); - set_emission_sphere_radius(1); - set_emission_rect_extents(Vector2(1, 1)); - - set_gravity(Vector2(0, 98)); for (int i = 0; i < PARAM_MAX; i++) { set_param_randomness(Parameter(i), 0); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 3793f6a418..7ee165b3e1 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -78,31 +78,31 @@ public: }; private: - bool emitting; + bool emitting = false; struct Particle { Transform2D transform; Color color; - float custom[4]; - float rotation; + float custom[4] = {}; + float rotation = 0.0; Vector2 velocity; - bool active; - float angle_rand; - float scale_rand; - float hue_rot_rand; - float anim_offset_rand; - float time; - float lifetime; + bool active = false; + float angle_rand = 0.0; + float scale_rand = 0.0; + float hue_rot_rand = 0.0; + float anim_offset_rand = 0.0; + float time = 0.0; + float lifetime = 0.0; Color base_color; - uint32_t seed; + uint32_t seed = 0; }; - float time; - float inactive_time; - float frame_remainder; - int cycle; - bool redraw; + float time = 0.0; + float inactive_time = 0.0; + float frame_remainder = 0.0; + int cycle = 0; + bool redraw = false; RID mesh; RID multimesh; @@ -112,7 +112,7 @@ private: Vector<int> particle_order; struct SortLifetime { - const Particle *particles; + const Particle *particles = nullptr; bool operator()(int p_a, int p_b) const { return particles[p_a].time > particles[p_b].time; @@ -120,7 +120,7 @@ private: }; struct SortAxis { - const Particle *particles; + const Particle *particles = nullptr; Vector2 axis; bool operator()(int p_a, int p_b) const { return axis.dot(particles[p_a].transform[2]) < axis.dot(particles[p_b].transform[2]); @@ -129,28 +129,28 @@ private: // - bool one_shot; + bool one_shot = false; - float lifetime; - float pre_process_time; - float explosiveness_ratio; - float randomness_ratio; - float lifetime_randomness; - float speed_scale; + float lifetime = 1.0; + float pre_process_time = 0.0; + float explosiveness_ratio = 0.0; + float randomness_ratio = 0.0; + float lifetime_randomness = 0.0; + float speed_scale = 1.0; bool local_coords; - int fixed_fps; - bool fractional_delta; + int fixed_fps = 0; + bool fractional_delta = true; Transform2D inv_emission_transform; - DrawOrder draw_order; + DrawOrder draw_order = DRAW_ORDER_INDEX; Ref<Texture2D> texture; //////// - Vector2 direction; - float spread; + Vector2 direction = Vector2(1, 0); + float spread = 45.0; float parameters[PARAM_MAX]; float randomness[PARAM_MAX]; @@ -161,15 +161,15 @@ private: bool particle_flags[PARTICLE_FLAG_MAX]; - EmissionShape emission_shape; - float emission_sphere_radius; - Vector2 emission_rect_extents; + EmissionShape emission_shape = EMISSION_SHAPE_POINT; + float emission_sphere_radius = 1.0; + Vector2 emission_rect_extents = Vector2(1, 1); Vector<Vector2> emission_points; Vector<Vector2> emission_normals; Vector<Color> emission_colors; - int emission_point_count; + int emission_point_count = 0; - Vector2 gravity; + Vector2 gravity = Vector2(0, 98); void _update_internal(); void _particles_process(float p_delta); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 2e477a88a9..af70c47f7c 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -101,7 +101,6 @@ void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) { RS::get_singleton()->particles_set_custom_aabb(particles, aabb); - _change_notify("visibility_rect"); update(); } @@ -305,7 +304,7 @@ void GPUParticles2D::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (one_shot && !is_emitting()) { - _change_notify(); + notify_property_list_changed(); set_process_internal(false); } } diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 1a31f72a59..f4f08674c9 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -65,18 +65,16 @@ void Joint2D::_body_exit_tree(const ObjectID &p_body_id) { } void Joint2D::_update_joint(bool p_only_free) { - if (joint.is_valid()) { - if (ba.is_valid() && bb.is_valid() && exclude_from_collision) { - PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false); - } - - PhysicsServer2D::get_singleton()->free(joint); - joint = RID(); - ba = RID(); - bb = RID(); + if (ba.is_valid() && bb.is_valid() && exclude_from_collision) { + PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false); } + ba = RID(); + bb = RID(); + configured = false; + if (p_only_free || !is_inside_tree()) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = String(); return; } @@ -88,30 +86,35 @@ void Joint2D::_update_joint(bool p_only_free) { PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); if (node_a && !body_a && node_b && !body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be PhysicsBody2Ds"); update_configuration_warning(); return; } if (node_a && !body_a) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node A must be a PhysicsBody2D"); update_configuration_warning(); return; } if (node_b && !body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node B must be a PhysicsBody2D"); update_configuration_warning(); return; } if (!body_a || !body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Joint is not connected to two PhysicsBody2Ds"); update_configuration_warning(); return; } if (body_a == body_b) { + PhysicsServer2D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be different PhysicsBody2Ds"); update_configuration_warning(); return; @@ -128,7 +131,9 @@ void Joint2D::_update_joint(bool p_only_free) { body_b->force_update_transform(); } - joint = _configure_joint(body_a, body_b); + configured = true; + + _configure_joint(joint, body_a, body_b); ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); @@ -249,8 +254,11 @@ void Joint2D::_bind_methods() { } Joint2D::Joint2D() { - bias = 0; - exclude_from_collision = true; + joint = PhysicsServer2D::get_singleton()->joint_create(); +} + +Joint2D::~Joint2D() { + PhysicsServer2D::get_singleton()->free(joint); } /////////////////////////////////////////////////////////////////////////////// @@ -274,16 +282,15 @@ void PinJoint2D::_notification(int p_what) { } } -RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { - RID pj = PhysicsServer2D::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID()); - PhysicsServer2D::get_singleton()->pin_joint_set_param(pj, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness); - return pj; +void PinJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) { + PhysicsServer2D::get_singleton()->joint_make_pin(p_joint, get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID()); + PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness); } void PinJoint2D::set_softness(real_t p_softness) { softness = p_softness; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer2D::PIN_JOINT_SOFTNESS, p_softness); } } @@ -300,7 +307,6 @@ void PinJoint2D::_bind_methods() { } PinJoint2D::PinJoint2D() { - softness = 0; } /////////////////////////////////////////////////////////////////////////////// @@ -326,13 +332,13 @@ void GrooveJoint2D::_notification(int p_what) { } } -RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { +void GrooveJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) { Transform2D gt = get_global_transform(); Vector2 groove_A1 = gt.get_origin(); Vector2 groove_A2 = gt.xform(Vector2(0, length)); Vector2 anchor_B = gt.xform(Vector2(0, initial_offset)); - return PhysicsServer2D::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid()); + PhysicsServer2D::get_singleton()->joint_make_groove(p_joint, groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid()); } void GrooveJoint2D::set_length(real_t p_length) { @@ -364,8 +370,6 @@ void GrooveJoint2D::_bind_methods() { } GrooveJoint2D::GrooveJoint2D() { - length = 50; - initial_offset = 25; } /////////////////////////////////////////////////////////////////////////////// @@ -390,19 +394,17 @@ void DampedSpringJoint2D::_notification(int p_what) { } } -RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) { +void DampedSpringJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) { Transform2D gt = get_global_transform(); Vector2 anchor_A = gt.get_origin(); Vector2 anchor_B = gt.xform(Vector2(0, length)); - RID dsj = PhysicsServer2D::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid()); + PhysicsServer2D::get_singleton()->joint_make_damped_spring(p_joint, anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid()); if (rest_length) { - PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length); + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length); } - PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness); - PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping); - - return dsj; + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness); + PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping); } void DampedSpringJoint2D::set_length(real_t p_length) { @@ -417,7 +419,7 @@ real_t DampedSpringJoint2D::get_length() const { void DampedSpringJoint2D::set_rest_length(real_t p_rest_length) { rest_length = p_rest_length; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, p_rest_length ? p_rest_length : length); } } @@ -429,7 +431,7 @@ real_t DampedSpringJoint2D::get_rest_length() const { void DampedSpringJoint2D::set_stiffness(real_t p_stiffness) { stiffness = p_stiffness; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_STIFFNESS, p_stiffness); } } @@ -441,7 +443,7 @@ real_t DampedSpringJoint2D::get_stiffness() const { void DampedSpringJoint2D::set_damping(real_t p_damping) { damping = p_damping; update(); - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_DAMPING, p_damping); } } @@ -467,8 +469,4 @@ void DampedSpringJoint2D::_bind_methods() { } DampedSpringJoint2D::DampedSpringJoint2D() { - length = 50; - rest_length = 0; - stiffness = 20; - damping = 1; } diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h index d0fbb9fd3a..3607a6c176 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joints_2d.h @@ -43,9 +43,10 @@ class Joint2D : public Node2D { NodePath a; NodePath b; - real_t bias; + real_t bias = 0.0; - bool exclude_from_collision; + bool exclude_from_collision = true; + bool configured = false; String warning; protected: @@ -54,10 +55,12 @@ protected: void _update_joint(bool p_only_free = false); void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0; static void _bind_methods(); + _FORCE_INLINE_ bool is_configured() const { return configured; } + public: virtual String get_configuration_warning() const override; @@ -75,16 +78,17 @@ public: RID get_joint() const { return joint; } Joint2D(); + ~Joint2D(); }; class PinJoint2D : public Joint2D { GDCLASS(PinJoint2D, Joint2D); - real_t softness; + real_t softness = 0.0; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: @@ -97,12 +101,12 @@ public: class GrooveJoint2D : public Joint2D { GDCLASS(GrooveJoint2D, Joint2D); - real_t length; - real_t initial_offset; + real_t length = 50.0; + real_t initial_offset = 25.0; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: @@ -118,14 +122,14 @@ public: class DampedSpringJoint2D : public Joint2D { GDCLASS(DampedSpringJoint2D, Joint2D); - real_t stiffness; - real_t damping; - real_t rest_length; - real_t length; + real_t stiffness = 20.0; + real_t damping = 1.0; + real_t rest_length = 0.0; + real_t length = 50.0; protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override; static void _bind_methods(); public: diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index ba4372f040..15fcb08422 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -300,22 +300,6 @@ void Light2D::_bind_methods() { Light2D::Light2D() { canvas_light = RenderingServer::get_singleton()->canvas_light_create(); - enabled = true; - editor_only = false; - shadow = false; - color = Color(1, 1, 1); - height = 0; - z_min = -1024; - z_max = 1024; - layer_min = 0; - layer_max = 0; - item_mask = 1; - item_shadow_mask = 1; - energy = 1.0; - shadow_color = Color(0, 0, 0, 0); - shadow_filter = SHADOW_FILTER_NONE; - shadow_smooth = 0; - blend_mode = BLEND_MODE_ADD; set_notify_transform(true); } @@ -393,7 +377,6 @@ void PointLight2D::set_texture_offset(const Vector2 &p_offset) { texture_offset = p_offset; RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset); item_rect_changed(); - _change_notify("offset"); } Vector2 PointLight2D::get_texture_offset() const { diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 0112ab1648..4279baf15b 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -52,24 +52,24 @@ public: private: RID canvas_light; - bool enabled; - bool editor_only; - bool shadow; - Color color; - Color shadow_color; - float height; - float energy; - int z_min; - int z_max; - int layer_min; - int layer_max; - int item_mask; - int item_shadow_mask; - float shadow_smooth; + bool enabled = true; + bool editor_only = false; + bool shadow = false; + Color color = Color(1, 1, 1); + Color shadow_color = Color(0, 0, 0, 0); + float height = 0.0; + float energy = 1.0; + int z_min = -1024; + int z_max = 1024; + int layer_min = 0; + int layer_max = 0; + int item_mask = 1; + int item_shadow_mask = 1; + float shadow_smooth = 0.0; Ref<Texture2D> texture; Vector2 texture_offset; - ShadowFilter shadow_filter; - BlendMode blend_mode; + ShadowFilter shadow_filter = SHADOW_FILTER_NONE; + BlendMode blend_mode = BLEND_MODE_ADD; void _update_light_visibility(); diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 3146e64c08..9589702e2e 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -145,9 +145,6 @@ void OccluderPolygon2D::_bind_methods() { OccluderPolygon2D::OccluderPolygon2D() { occ_polygon = RS::get_singleton()->canvas_occluder_polygon_create(); - closed = true; - cull = CULL_DISABLED; - rect_cache_dirty = true; } OccluderPolygon2D::~OccluderPolygon2D() { diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 7944ccad3a..f567c6d965 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -46,11 +46,11 @@ public: private: RID occ_polygon; Vector<Vector2> polygon; - bool closed; - CullMode cull; + bool closed = true; + CullMode cull = CULL_DISABLED; mutable Rect2 item_rect; - mutable bool rect_cache_dirty; + mutable bool rect_cache_dirty = true; protected: static void _bind_methods(); diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 0a3f5673f8..2959ea1a36 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -40,15 +40,6 @@ VARIANT_ENUM_CAST(Line2D::LineCapMode) VARIANT_ENUM_CAST(Line2D::LineTextureMode) Line2D::Line2D() { - _joint_mode = LINE_JOINT_SHARP; - _begin_cap_mode = LINE_CAP_NONE; - _end_cap_mode = LINE_CAP_NONE; - _width = 10; - _default_color = Color(1, 1, 1); - _texture_mode = LINE_TEXTURE_NONE; - _sharp_limit = 2.f; - _round_precision = 8; - _antialiased = false; } #ifdef TOOLS_ENABLED diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index e0b1cea60a..5e7eb4bac9 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -124,18 +124,18 @@ private: private: Vector<Vector2> _points; - LineJointMode _joint_mode; - LineCapMode _begin_cap_mode; - LineCapMode _end_cap_mode; - float _width; + LineJointMode _joint_mode = LINE_JOINT_SHARP; + LineCapMode _begin_cap_mode = LINE_CAP_NONE; + LineCapMode _end_cap_mode = LINE_CAP_NONE; + float _width = 10.0; Ref<Curve> _curve; - Color _default_color; + Color _default_color = Color(1, 1, 1); Ref<Gradient> _gradient; Ref<Texture2D> _texture; - LineTextureMode _texture_mode; - float _sharp_limit; - int _round_precision; - bool _antialiased; + LineTextureMode _texture_mode = LINE_TEXTURE_NONE; + float _sharp_limit = 2.f; + int _round_precision = 8; + bool _antialiased = false; }; #endif // LINE2D_H diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 2f4459785b..892ccadfda 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -94,20 +94,6 @@ static inline Vector2 interpolate(const Rect2 &r, const Vector2 &v) { //---------------------------------------------------------------------------- LineBuilder::LineBuilder() { - joint_mode = Line2D::LINE_JOINT_SHARP; - width = 10; - curve = nullptr; - default_color = Color(0.4, 0.5, 1); - gradient = nullptr; - sharp_limit = 2.f; - round_precision = 8; - begin_cap_mode = Line2D::LINE_CAP_NONE; - end_cap_mode = Line2D::LINE_CAP_NONE; - tile_aspect = 1.f; - - _interpolate_color = false; - _last_index[0] = 0; - _last_index[1] = 0; } void LineBuilder::clear_output() { @@ -554,7 +540,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col float t = Vector2(1, 0).angle_to(vbegin); float end_angle = t + angle_delta; Vector2 rpos(0, 0); - float tt_begin = -Math_PI / 2.f; + float tt_begin = -Math_PI / 2.0f; float tt = tt_begin; // Center vertice diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index bd419d330b..654e61422b 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -41,17 +41,17 @@ public: // TODO Move in a struct and reference it // Input Vector<Vector2> points; - Line2D::LineJointMode joint_mode; - Line2D::LineCapMode begin_cap_mode; - Line2D::LineCapMode end_cap_mode; - float width; - Curve *curve; - Color default_color; - Gradient *gradient; - Line2D::LineTextureMode texture_mode; - float sharp_limit; - int round_precision; - float tile_aspect; // w/h + Line2D::LineJointMode joint_mode = Line2D::LINE_JOINT_SHARP; + Line2D::LineCapMode begin_cap_mode = Line2D::LINE_CAP_NONE; + Line2D::LineCapMode end_cap_mode = Line2D::LINE_CAP_NONE; + float width = 10.0; + Curve *curve = nullptr; + Color default_color = Color(0.4, 0.5, 1); + Gradient *gradient = nullptr; + Line2D::LineTextureMode texture_mode = Line2D::LineTextureMode::LINE_TEXTURE_NONE; + float sharp_limit = 2.f; + int round_precision = 8; + float tile_aspect = 1.f; // w/h // TODO offset_joints option (offers alternative implementation of round joints) // TODO Move in a struct and reference it @@ -82,8 +82,8 @@ private: void new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Color color, Rect2 uv_rect); private: - bool _interpolate_color; - int _last_index[2]; // Index of last up and down vertices of the strip + bool _interpolate_color = false; + int _last_index[2] = {}; // Index of last up and down vertices of the strip }; #endif // LINE_BUILDER_H diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 430e655fc6..b7a0028199 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -71,7 +71,6 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); emit_signal("texture_changed"); - _change_notify("texture"); } void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 5164e5c7e9..72a899370e 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -71,7 +71,6 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); emit_signal("texture_changed"); - _change_notify("texture"); } Ref<Texture2D> MultiMeshInstance2D::get_texture() const { diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 7360fce330..b02cdf12ad 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -481,7 +481,6 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_ } _navpoly_changed(); - _change_notify("navpoly"); update_configuration_warning(); } diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 70a4e3f0fb..bf311632c8 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -53,12 +53,6 @@ void Node2D::_edit_set_state(const Dictionary &p_state) { skew = p_state["skew"]; _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); - _change_notify("scale"); - _change_notify("skew"); - _change_notify("skew_degrees"); - _change_notify("position"); } void Node2D::_edit_set_position(const Point2 &p_position) { @@ -80,8 +74,6 @@ Size2 Node2D::_edit_get_scale() const { void Node2D::_edit_set_rotation(float p_rotation) { angle = p_rotation; _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); } float Node2D::_edit_get_rotation() const { @@ -124,8 +116,6 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { _scale *= new_scale; _update_transform(); - _change_notify("scale"); - _change_notify("position"); } #endif @@ -156,7 +146,6 @@ void Node2D::set_position(const Point2 &p_pos) { } pos = p_pos; _update_transform(); - _change_notify("position"); } void Node2D::set_rotation(float p_radians) { @@ -165,8 +154,6 @@ void Node2D::set_rotation(float p_radians) { } angle = p_radians; _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); } void Node2D::set_skew(float p_radians) { @@ -175,8 +162,6 @@ void Node2D::set_skew(float p_radians) { } skew = p_radians; _update_transform(); - _change_notify("skew"); - _change_notify("skew_degrees"); } void Node2D::set_rotation_degrees(float p_degrees) { @@ -200,7 +185,6 @@ void Node2D::set_scale(const Size2 &p_scale) { _scale.y = CMP_EPSILON; } _update_transform(); - _change_notify("scale"); } Point2 Node2D::get_position() const { @@ -358,7 +342,6 @@ void Node2D::set_z_index(int p_z) { ERR_FAIL_COND(p_z > RS::CANVAS_ITEM_Z_MAX); z_index = p_z; RS::get_singleton()->canvas_item_set_z_index(get_canvas_item(), z_index); - _change_notify("z_index"); } void Node2D::set_z_as_relative(bool p_enabled) { diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index a5ae5dae0e..c27d740b8a 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -37,9 +37,9 @@ class Node2D : public CanvasItem { GDCLASS(Node2D, CanvasItem); Point2 pos; - float angle = 0; + float angle = 0.0; Size2 _scale = Vector2(1, 1); - float skew = 0; + float skew = 0.0; int z_index = 0; bool z_relative = true; diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index a35ffaa668..c93915d1bc 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -185,9 +185,5 @@ void ParallaxBackground::_bind_methods() { } ParallaxBackground::ParallaxBackground() { - scale = 1.0; set_layer(-100); //behind all by default - - base_scale = Vector2(1, 1); - ignore_camera_zoom = false; } diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 578e615be9..c9991efc9d 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -39,15 +39,15 @@ class ParallaxBackground : public CanvasLayer { GDCLASS(ParallaxBackground, CanvasLayer); Point2 offset; - float scale; + float scale = 1.0; Point2 base_offset; - Point2 base_scale; + Point2 base_scale = Vector2(1, 1); Point2 screen_offset; String group_name; Point2 limit_begin; Point2 limit_end; Point2 final_offset; - bool ignore_camera_zoom; + bool ignore_camera_zoom = false; void _update_scroll(); diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 129082cb91..a38338e1e3 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -163,5 +163,4 @@ void ParallaxLayer::_bind_methods() { } ParallaxLayer::ParallaxLayer() { - motion_scale = Size2(1, 1); } diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index b6895b0aca..86694c7724 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -38,7 +38,7 @@ class ParallaxLayer : public Node2D { Point2 orig_offset; Point2 orig_scale; - Size2 motion_scale; + Size2 motion_scale = Size2(1, 1); Vector2 motion_offset; Vector2 mirroring; void _update_mirroring(); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 41c91115ad..724998641f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -240,7 +240,7 @@ bool PathFollow2D::get_cubic_interpolation() const { void PathFollow2D::_validate_property(PropertyInfo &property) const { if (property.name == "offset") { - float max = 10000; + float max = 10000.0; if (path && path->get_curve().is_valid()) { max = path->get_curve()->get_baked_length(); } @@ -319,8 +319,6 @@ void PathFollow2D::set_offset(float p_offset) { _update_transform(); } - _change_notify("offset"); - _change_notify("unit_offset"); } void PathFollow2D::set_h_offset(float p_h_offset) { diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 3c5e0e4180..a748817555 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -64,10 +64,10 @@ class PathFollow2D : public Node2D { public: private: Path2D *path = nullptr; - real_t offset = 0; - real_t h_offset = 0; - real_t v_offset = 0; - real_t lookahead = 4; + real_t offset = 0.0; + real_t h_offset = 0.0; + real_t v_offset = 0.0; + real_t lookahead = 4.0; bool cubic = true; bool loop = true; bool rotates = true; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index a65009d072..96d8fb609b 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -111,8 +111,6 @@ bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const { PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : CollisionObject2D(PhysicsServer2D::get_singleton()->body_create(), false) { PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), p_mode); - collision_layer = 1; - collision_mask = 1; set_pickable(false); } @@ -197,7 +195,6 @@ void StaticBody2D::_bind_methods() { StaticBody2D::StaticBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) { - constant_angular_velocity = 0; } StaticBody2D::~StaticBody2D() { @@ -320,11 +317,11 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap struct _RigidBody2DInOut { ObjectID id; - int shape; - int local_shape; + int shape = 0; + int local_shape = 0; }; -bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { +bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { PhysicsServer2D::MotionResult *r = nullptr; if (p_result.is_valid()) { r = p_result->get_result_ptr(); @@ -611,7 +608,7 @@ void RigidBody2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_posit PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position); } -void RigidBody2D::apply_torque_impulse(float p_torque) { +void RigidBody2D::apply_torque_impulse(real_t p_torque) { PhysicsServer2D::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque); } @@ -623,11 +620,11 @@ Vector2 RigidBody2D::get_applied_force() const { return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid()); }; -void RigidBody2D::set_applied_torque(const float p_torque) { +void RigidBody2D::set_applied_torque(const real_t p_torque) { PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque); }; -float RigidBody2D::get_applied_torque() const { +real_t RigidBody2D::get_applied_torque() const { return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid()); }; @@ -639,7 +636,7 @@ void RigidBody2D::add_force(const Vector2 &p_force, const Vector2 &p_position) { PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_force, p_position); } -void RigidBody2D::add_torque(const float p_torque) { +void RigidBody2D::add_torque(const real_t p_torque) { PhysicsServer2D::get_singleton()->body_add_torque(get_rid(), p_torque); } @@ -841,25 +838,6 @@ void RigidBody2D::_bind_methods() { RigidBody2D::RigidBody2D() : PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { - mode = MODE_RIGID; - - mass = 1; - - gravity_scale = 1; - linear_damp = -1; - angular_damp = -1; - - max_contacts_reported = 0; - state = nullptr; - - angular_velocity = 0; - sleeping = false; - ccd_mode = CCD_MODE_DISABLED; - - custom_integrator = false; - contact_monitor = nullptr; - can_sleep = true; - PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -906,7 +884,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision Vector2 recover; int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; - float deepest_depth; + real_t deepest_depth; for (int i = 0; i < hits; i++) { if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) { deepest = i; @@ -966,7 +944,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector2 body_velocity = p_linear_velocity; Vector2 body_velocity_normal = body_velocity.normalized(); Vector2 up_direction = p_up_direction.normalized(); @@ -1057,7 +1035,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const return body_velocity; } -Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector2 up_direction = p_up_direction.normalized(); bool was_on_floor = on_floor; @@ -1123,11 +1101,11 @@ bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_moti return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin); } -void KinematicBody2D::set_safe_margin(float p_margin) { +void KinematicBody2D::set_safe_margin(real_t p_margin) { margin = p_margin; } -float KinematicBody2D::get_safe_margin() const { +real_t KinematicBody2D::get_safe_margin() const { return margin; } @@ -1219,8 +1197,8 @@ void KinematicBody2D::_notification(int p_what) { void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true)); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 159f73b269..2dc853b23b 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -41,8 +41,8 @@ class KinematicCollision2D; class PhysicsBody2D : public CollisionObject2D { GDCLASS(PhysicsBody2D, CollisionObject2D); - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; protected: void _notification(int p_what); @@ -74,7 +74,7 @@ class StaticBody2D : public PhysicsBody2D { GDCLASS(StaticBody2D, PhysicsBody2D); Vector2 constant_linear_velocity; - real_t constant_angular_velocity; + real_t constant_angular_velocity = 0.0; Ref<PhysicsMaterial> physics_material_override; @@ -116,30 +116,30 @@ public: }; private: - bool can_sleep; - PhysicsDirectBodyState2D *state; - Mode mode; + bool can_sleep = true; + PhysicsDirectBodyState2D *state = nullptr; + Mode mode = MODE_RIGID; - real_t mass; + real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; - real_t gravity_scale; - real_t linear_damp; - real_t angular_damp; + real_t gravity_scale = 1.0; + real_t linear_damp = -1.0; + real_t angular_damp = -1.0; Vector2 linear_velocity; - real_t angular_velocity; - bool sleeping; + real_t angular_velocity = 0.0; + bool sleeping = false; - int max_contacts_reported; + int max_contacts_reported = 0; - bool custom_integrator; + bool custom_integrator = false; - CCDMode ccd_mode; + CCDMode ccd_mode = CCD_MODE_DISABLED; struct ShapePair { - int body_shape; - int local_shape; - bool tagged; + int body_shape = 0; + int local_shape = 0; + bool tagged = false; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return local_shape < p_sp.local_shape; @@ -160,23 +160,23 @@ private: }; struct BodyState { //int rc; - bool in_scene; + bool in_scene = false; VSet<ShapePair> shapes; }; struct ContactMonitor { - bool locked; + bool locked = false; Map<ObjectID, BodyState> body_map; }; - ContactMonitor *contact_monitor; + ContactMonitor *contact_monitor = nullptr; void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape); void _direct_state_changed(Object *p_state); - bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, float p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); + bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); protected: void _notification(int p_what); @@ -232,17 +232,17 @@ public: void apply_central_impulse(const Vector2 &p_impulse); void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()); - void apply_torque_impulse(float p_torque); + void apply_torque_impulse(real_t p_torque); void set_applied_force(const Vector2 &p_force); Vector2 get_applied_force() const; - void set_applied_torque(const float p_torque); - float get_applied_torque() const; + void set_applied_torque(const real_t p_torque); + real_t get_applied_torque() const; void add_central_force(const Vector2 &p_force); void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()); - void add_torque(float p_torque); + void add_torque(real_t p_torque); TypedArray<Node2D> get_colliding_bodies() const; //function for script @@ -268,15 +268,15 @@ public: Vector2 collider_vel; ObjectID collider; RID collider_rid; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; Vector2 remainder; Vector2 travel; - int local_shape; + int local_shape = 0; }; private: - float margin; + real_t margin; Vector2 floor_normal; Vector2 floor_velocity; @@ -309,11 +309,11 @@ public: bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); - void set_safe_margin(float p_margin); - float get_safe_margin() const; + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); + Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 82e1b7ac96..ecc05fb931 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -155,7 +155,7 @@ void Polygon2D::_notification(int p_what) { Rect2 bounds; int highest_idx = -1; float highest_y = -1e20; - float sum = 0; + float sum = 0.0; for (int i = 0; i < len; i++) { if (i == 0) { @@ -273,7 +273,7 @@ void Polygon2D::_notification(int p_what) { //normalize the weights for (int i = 0; i < vc; i++) { - float tw = 0; + float tw = 0.0; for (int j = 0; j < 4; j++) { tw += weightsw[i * 4 + j]; } @@ -483,7 +483,6 @@ void Polygon2D::set_offset(const Vector2 &p_offset) { offset = p_offset; rect_cache_dirty = true; update(); - _change_notify("offset"); } Vector2 Polygon2D::get_offset() const { @@ -649,13 +648,4 @@ void Polygon2D::_bind_methods() { } Polygon2D::Polygon2D() { - invert = false; - invert_border = 100; - antialiased = false; - tex_rot = 0; - tex_tile = true; - tex_scale = Vector2(1, 1); - color = Color(1, 1, 1); - rect_cache_dirty = true; - internal_vertices = 0; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index cdb3052225..ab01a4ffd0 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -40,7 +40,7 @@ class Polygon2D : public Node2D { Vector<Vector2> uv; Vector<Color> vertex_colors; Array polygons; - int internal_vertices; + int internal_vertices = 0; struct Bone { NodePath path; @@ -49,19 +49,19 @@ class Polygon2D : public Node2D { Vector<Bone> bone_weights; - Color color; + Color color = Color(1, 1, 1); Ref<Texture2D> texture; - Size2 tex_scale; + Size2 tex_scale = Vector2(1, 1); Vector2 tex_ofs; - bool tex_tile; - float tex_rot; - bool invert; - float invert_border; - bool antialiased; + bool tex_tile = true; + float tex_rot = 0.0; + bool invert = false; + float invert_border = 100.0; + bool antialiased = false; Vector2 offset; - mutable bool rect_cache_dirty; + mutable bool rect_cache_dirty = true; mutable Rect2 item_rect; NodePath skeleton; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 2c4a549acf..2cc3a74270 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -173,7 +173,7 @@ void RayCast2D::_notification(int p_what) { } draw_line(Vector2(), target_position, draw_col, 2); Vector<Vector2> pts; - float tsize = 8; + float tsize = 8.0; pts.push_back(xf.xform(Vector2(tsize, 0))); pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize))); pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize))); @@ -325,12 +325,4 @@ void RayCast2D::_bind_methods() { } RayCast2D::RayCast2D() { - enabled = true; - collided = false; - against_shape = 0; - collision_mask = 1; - target_position = Vector2(0, 50); - exclude_parent_body = true; - collide_with_bodies = true; - collide_with_areas = false; } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index ff7a970ebf..dab3302e25 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -36,20 +36,20 @@ class RayCast2D : public Node2D { GDCLASS(RayCast2D, Node2D); - bool enabled; - bool collided; + bool enabled = true; + bool collided = false; ObjectID against; - int against_shape; + int against_shape = 0; Vector2 collision_point; Vector2 collision_normal; Set<RID> exclude; - uint32_t collision_mask; - bool exclude_parent_body; + uint32_t collision_mask = 1; + bool exclude_parent_body = true; - Vector2 target_position; + Vector2 target_position = Vector2(0, 50); - bool collide_with_areas; - bool collide_with_bodies; + bool collide_with_areas = false; + bool collide_with_bodies = true; protected: void _notification(int p_what); diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 4ed4c3a8ff..f10714e28a 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -223,10 +223,5 @@ void RemoteTransform2D::_bind_methods() { } RemoteTransform2D::RemoteTransform2D() { - use_global_coordinates = true; - update_remote_position = true; - update_remote_rotation = true; - update_remote_scale = true; - set_notify_transform(true); } diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index cb4bd37f1f..4a26d7b339 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -40,10 +40,10 @@ class RemoteTransform2D : public Node2D { ObjectID cache; - bool use_global_coordinates; - bool update_remote_position; - bool update_remote_rotation; - bool update_remote_scale; + bool use_global_coordinates = true; + bool update_remote_position = true; + bool update_remote_rotation = true; + bool update_remote_scale = true; void _update_remote(); void _update_cache(); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index bb5a309f65..5728230a8c 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -157,10 +157,6 @@ String Bone2D::get_configuration_warning() const { } Bone2D::Bone2D() { - skeleton = nullptr; - parent_bone = nullptr; - skeleton_index = -1; - default_length = 16; set_notify_local_transform(true); //this is a clever hack so the bone knows no rest has been set yet, allowing to show an error. for (int i = 0; i < 3; i++) { @@ -186,7 +182,7 @@ void Skeleton2D::_update_bone_setup() { } bone_setup_dirty = false; - RS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true); + RS::get_singleton()->skeleton_allocate_data(skeleton, bones.size(), true); bones.sort(); //sorty so they are always in the same order/index @@ -293,9 +289,6 @@ void Skeleton2D::_bind_methods() { } Skeleton2D::Skeleton2D() { - bone_setup_dirty = true; - transform_dirty = true; - skeleton = RS::get_singleton()->skeleton_create(); set_notify_transform(true); } diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index 36b9e1b339..80ca8c80ac 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -43,12 +43,12 @@ class Bone2D : public Node2D { friend class AnimatedValuesBackup; #endif - Bone2D *parent_bone; - Skeleton2D *skeleton; + Bone2D *parent_bone = nullptr; + Skeleton2D *skeleton = nullptr; Transform2D rest; - float default_length; + float default_length = 16.0; - int skeleton_index; + int skeleton_index = -1; protected: void _notification(int p_what); @@ -82,19 +82,19 @@ class Skeleton2D : public Node2D { bool operator<(const Bone &p_bone) const { return p_bone.bone->is_greater_than(bone); } - Bone2D *bone; - int parent_index; + Bone2D *bone = nullptr; + int parent_index = 0; Transform2D accum_transform; Transform2D rest_inverse; }; Vector<Bone> bones; - bool bone_setup_dirty; + bool bone_setup_dirty = true; void _make_bone_setup_dirty(); void _update_bone_setup(); - bool transform_dirty; + bool transform_dirty = true; void _make_transform_dirty(); void _update_transform(); diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index 773214deeb..dde9790b44 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -155,7 +155,6 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { update(); emit_signal("texture_changed"); item_rect_changed(); - _change_notify("texture"); } Ref<Texture2D> Sprite2D::get_texture() const { @@ -176,7 +175,6 @@ void Sprite2D::set_offset(const Point2 &p_offset) { offset = p_offset; update(); item_rect_changed(); - _change_notify("offset"); } Point2 Sprite2D::get_offset() const { @@ -224,8 +222,6 @@ void Sprite2D::set_region_rect(const Rect2 &p_region_rect) { if (region) { item_rect_changed(); } - - _change_notify("region_rect"); } Rect2 Sprite2D::get_region_rect() const { @@ -250,8 +246,6 @@ void Sprite2D::set_frame(int p_frame) { frame = p_frame; - _change_notify("frame"); - _change_notify("frame_coords"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -275,7 +269,7 @@ void Sprite2D::set_vframes(int p_amount) { vframes = p_amount; update(); item_rect_changed(); - _change_notify(); + notify_property_list_changed(); } int Sprite2D::get_vframes() const { @@ -287,7 +281,7 @@ void Sprite2D::set_hframes(int p_amount) { hframes = p_amount; update(); item_rect_changed(); - _change_notify(); + notify_property_list_changed(); } int Sprite2D::get_hframes() const { @@ -462,16 +456,6 @@ void Sprite2D::_bind_methods() { } Sprite2D::Sprite2D() { - centered = true; - hflip = false; - vflip = false; - region = false; - region_filter_clip = false; - - frame = 0; - - vframes = 1; - hframes = 1; } Sprite2D::~Sprite2D() { diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h index 716882d485..fa765f457d 100644 --- a/scene/2d/sprite_2d.h +++ b/scene/2d/sprite_2d.h @@ -39,21 +39,21 @@ class Sprite2D : public Node2D { Ref<Texture2D> texture; Color specular_color; - float shininess; + float shininess = 0.0; - bool centered; + bool centered = true; Point2 offset; - bool hflip; - bool vflip; - bool region; + bool hflip = false; + bool vflip = false; + bool region = false; Rect2 region_rect; - bool region_filter_clip; + bool region_filter_clip = false; - int frame; + int frame = 0; - int vframes; - int hframes; + int vframes = 1; + int hframes = 1; void _get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 01b7a9c260..d868ebae25 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -165,7 +165,6 @@ void TileMap::_update_quadrant_transform() { void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { if (tile_set.is_valid()) { tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); - tile_set->remove_change_receptor(this); } _clear_quadrants(); @@ -173,7 +172,6 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { if (tile_set.is_valid()) { tile_set->connect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); - tile_set->add_change_receptor(this); } else { clear(); } @@ -1330,7 +1328,7 @@ void TileMap::set_collision_use_parent(bool p_use_parent) { } _recreate_quadrants(); - _change_notify(); + notify_property_list_changed(); update_configuration_warning(); } @@ -1865,47 +1863,11 @@ void TileMap::_bind_methods() { BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT); } -void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { - if (tile_set.is_valid() && tile_set.ptr() == p_changed) { - emit_signal("settings_changed"); - } -} - TileMap::TileMap() { - rect_cache_dirty = true; - used_size_cache_dirty = true; - pending_update = false; - quadrant_order_dirty = false; - quadrant_size = 16; - cell_size = Size2(64, 64); - custom_transform = Transform2D(64, 0, 0, 64, 0, 0); - collision_layer = 1; - collision_mask = 1; - friction = 1; - bounce = 0; - mode = MODE_SQUARE; - half_offset = HALF_OFFSET_DISABLED; - use_parent = false; - collision_parent = nullptr; - use_kinematic = false; - navigation = nullptr; - use_y_sort = false; - compatibility_mode = false; - centered_textures = false; - occluder_light_mask = 1; - clip_uv = false; - format = FORMAT_1; // Assume lowest possible format if none is present - - fp_adjust = 0.00001; - tile_origin = TILE_ORIGIN_TOP_LEFT; set_notify_transform(true); set_notify_local_transform(false); } TileMap::~TileMap() { - if (tile_set.is_valid()) { - tile_set->remove_change_receptor(this); - } - clear(); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index b1e54aafae..3bf4587921 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -70,22 +70,22 @@ private: }; Ref<TileSet> tile_set; - Size2i cell_size; - int quadrant_size; - Mode mode; - Transform2D custom_transform; - HalfOffset half_offset; - bool use_parent; - CollisionObject2D *collision_parent; - bool use_kinematic; - Navigation2D *navigation; + Size2i cell_size = Size2(64, 64); + int quadrant_size = 16; + Mode mode = MODE_SQUARE; + Transform2D custom_transform = Transform2D(64, 0, 0, 64, 0, 0); + HalfOffset half_offset = HALF_OFFSET_DISABLED; + bool use_parent = false; + CollisionObject2D *collision_parent = nullptr; + bool use_kinematic = false; + Navigation2D *navigation = nullptr; union PosKey { struct { int16_t x; int16_t y; }; - uint32_t key; + uint32_t key = 0; //using a more precise comparison so the regions can be sorted later bool operator<(const PosKey &p_k) const { return (y == p_k.y) ? x < p_k.x : y < p_k.y; } @@ -119,8 +119,7 @@ private: int16_t autotile_coord_y : 16; }; - uint64_t _u64t; - Cell() { _u64t = 0; } + uint64_t _u64t = 0; }; Map<PosKey, Cell> tile_map; @@ -130,7 +129,7 @@ private: Vector2 pos; List<RID> canvas_items; RID body; - uint32_t shape_owner_id; + uint32_t shape_owner_id = 0; SelfList<Quadrant> dirty_list; @@ -176,27 +175,27 @@ private: SelfList<Quadrant>::List dirty_quadrant_list; - bool pending_update; + bool pending_update = false; Rect2 rect_cache; - bool rect_cache_dirty; + bool rect_cache_dirty = true; Rect2 used_size_cache; - bool used_size_cache_dirty; - bool quadrant_order_dirty; - bool use_y_sort; - bool compatibility_mode; - bool centered_textures; - bool clip_uv; - float fp_adjust; - float friction; - float bounce; - uint32_t collision_layer; - uint32_t collision_mask; - mutable DataFormat format; - - TileOrigin tile_origin; - - int occluder_light_mask; + bool used_size_cache_dirty = true; + bool quadrant_order_dirty = false; + bool use_y_sort = false; + bool compatibility_mode = false; + bool centered_textures = false; + bool clip_uv = false; + float fp_adjust = 0.00001; + float friction = 1.0; + float bounce = 0.0; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; + mutable DataFormat format = FORMAT_1; // Assume lowest possible format if none is present + + TileOrigin tile_origin = TILE_ORIGIN_TOP_LEFT; + + int occluder_light_mask = 1; void _fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc); @@ -233,7 +232,6 @@ protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; public: enum { diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 04a1aedcd3..fccf126dad 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -399,11 +399,6 @@ void TouchScreenButton::_bind_methods() { } TouchScreenButton::TouchScreenButton() { - finger_pressed = -1; - passby_press = false; - visibility = VISIBILITY_ALWAYS; - shape_centered = true; - shape_visible = true; unit_rect = Ref<RectangleShape2D>(memnew(RectangleShape2D)); unit_rect->set_size(Vector2(1, 1)); } diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index f4ae3ca26c..10820ad059 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -50,16 +50,16 @@ private: Ref<Texture2D> texture_pressed; Ref<BitMap> bitmask; Ref<Shape2D> shape; - bool shape_centered; - bool shape_visible; + bool shape_centered = true; + bool shape_visible = true; Ref<RectangleShape2D> unit_rect; StringName action; - bool passby_press; - int finger_pressed; + bool passby_press = false; + int finger_pressed = -1; - VisibilityMode visibility; + VisibilityMode visibility = VISIBILITY_ALWAYS; void _input(const Ref<InputEvent> &p_event); diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index f3dddd5af8..916038a1f3 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -89,8 +89,6 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { item_rect_changed(); } } - - _change_notify("rect"); } Rect2 VisibilityNotifier2D::get_rect() const { @@ -363,6 +361,4 @@ VisibilityEnabler2D::VisibilityEnabler2D() { } enabler[ENABLER_PARENT_PROCESS] = false; enabler[ENABLER_PARENT_PHYSICS_PROCESS] = false; - - visible = false; } diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index ea3b5df37b..3d1701a1e5 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -85,7 +85,7 @@ protected: virtual void _screen_enter() override; virtual void _screen_exit() override; - bool visible; + bool visible = false; void _find_nodes(Node *p_node); diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp index 987e4581f4..7e7bc27cc2 100644 --- a/scene/2d/y_sort.cpp +++ b/scene/2d/y_sort.cpp @@ -48,6 +48,5 @@ void YSort::_bind_methods() { } YSort::YSort() { - sort_enabled = true; RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true); } diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h index 0882a88e3a..7d36ee3391 100644 --- a/scene/2d/y_sort.h +++ b/scene/2d/y_sort.h @@ -35,7 +35,7 @@ class YSort : public Node2D { GDCLASS(YSort, Node2D); - bool sort_enabled; + bool sort_enabled = true; static void _bind_methods(); public: diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 36312482cd..99c5276636 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -681,29 +681,10 @@ void Area3D::_bind_methods() { Area3D::Area3D() : CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) { - space_override = SPACE_OVERRIDE_DISABLED; set_gravity(9.8); - locked = false; set_gravity_vector(Vector3(0, -1, 0)); - gravity_is_point = false; - gravity_distance_scale = 0; - linear_damp = 0.1; - angular_damp = 0.1; - priority = 0; - monitoring = false; - monitorable = false; - collision_mask = 1; - collision_layer = 1; set_monitoring(true); set_monitorable(true); - - audio_bus_override = false; - audio_bus = "Master"; - - use_reverb_bus = false; - reverb_bus = "Master"; - reverb_amount = 0.0; - reverb_uniformity = 0.0; } Area3D::~Area3D() { diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 5d8e1933ba..6d976115f7 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -47,19 +47,19 @@ public: }; private: - SpaceOverride space_override; + SpaceOverride space_override = SPACE_OVERRIDE_DISABLED; Vector3 gravity_vec; real_t gravity; - bool gravity_is_point; - real_t gravity_distance_scale; - real_t angular_damp; - real_t linear_damp; - uint32_t collision_mask; - uint32_t collision_layer; - int priority; - bool monitoring; - bool monitorable; - bool locked; + bool gravity_is_point = false; + real_t gravity_distance_scale = 0.0; + real_t angular_damp = 0.1; + real_t linear_damp = 0.1; + uint32_t collision_mask = 1; + uint32_t collision_layer = 1; + int priority = 0; + bool monitoring = false; + bool monitorable = false; + bool locked = false; void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); @@ -67,8 +67,8 @@ private: void _body_exit_tree(ObjectID p_id); struct ShapePair { - int body_shape; - int area_shape; + int body_shape = 0; + int area_shape = 0; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return area_shape < p_sp.area_shape; @@ -85,8 +85,8 @@ private: }; struct BodyState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<ShapePair> shapes; }; @@ -98,8 +98,8 @@ private: void _area_exit_tree(ObjectID p_id); struct AreaShapePair { - int area_shape; - int self_shape; + int area_shape = 0; + int self_shape = 0; bool operator<(const AreaShapePair &p_sp) const { if (area_shape == p_sp.area_shape) { return self_shape < p_sp.self_shape; @@ -116,21 +116,21 @@ private: }; struct AreaState { - int rc; - bool in_tree; + int rc = 0; + bool in_tree = false; VSet<AreaShapePair> shapes; }; Map<ObjectID, AreaState> area_map; void _clear_monitoring(); - bool audio_bus_override; - StringName audio_bus; + bool audio_bus_override = false; + StringName audio_bus = "Master"; - bool use_reverb_bus; - StringName reverb_bus; - float reverb_amount; - float reverb_uniformity; + bool use_reverb_bus = false; + StringName reverb_bus = "Master"; + float reverb_amount = 0.0; + float reverb_uniformity = 0.0; void _validate_property(PropertyInfo &property) const override; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 2bcf898ced..d420bd6075 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -42,8 +42,8 @@ class Spcap { private: struct Speaker { Vector3 direction; - real_t effective_number_of_speakers; // precalculated - mutable real_t squared_gain; // temporary + real_t effective_number_of_speakers = 0; // precalculated + mutable real_t squared_gain = 0; // temporary }; Vector<Speaker> speakers; @@ -605,15 +605,11 @@ void AudioStreamPlayer3D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - //do not update, this makes it easier to animate (will shut off otherwise) - ///_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_physics_process_internal(false); - //do not update, this makes it easier to animate (will shut off otherwise) - //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -776,7 +772,7 @@ void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer3D::_bus_layout_changed() { - _change_notify(); + notify_property_list_changed(); } void AudioStreamPlayer3D::set_max_distance(float p_metres) { @@ -809,7 +805,6 @@ void AudioStreamPlayer3D::set_emission_angle(float p_angle) { ERR_FAIL_COND(p_angle < 0 || p_angle > 90); emission_angle = p_angle; update_gizmo(); - _change_notify("emission_angle"); } float AudioStreamPlayer3D::get_emission_angle() const { @@ -1002,31 +997,6 @@ void AudioStreamPlayer3D::_bind_methods() { } AudioStreamPlayer3D::AudioStreamPlayer3D() { - unit_db = 0; - unit_size = 1; - attenuation_model = ATTENUATION_INVERSE_DISTANCE; - max_db = 3; - pitch_scale = 1.0; - autoplay = false; - setseek = -1; - active = false; - output_count = 0; - prev_output_count = 0; - max_distance = 0; - setplay = -1; - output_ready = false; - area_mask = 1; - emission_angle = 45; - emission_angle_enabled = false; - emission_angle_filter_attenuation_db = -12; - attenuation_filter_cutoff_hz = 5000; - attenuation_filter_db = -24; - out_of_range_mode = OUT_OF_RANGE_MIX; - doppler_tracking = DOPPLER_TRACKING_DISABLED; - stream_paused = false; - stream_paused_fade_in = false; - stream_paused_fade_out = false; - velocity_tracker.instance(); AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed)); set_disable_scale(true); diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index bcfe2b2229..33ed758749 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -71,46 +71,39 @@ private: AudioFilterSW filter; AudioFilterSW::Processor filter_process[8]; AudioFrame vol[4]; - float filter_gain; - float pitch_scale; - int bus_index; - int reverb_bus_index; + float filter_gain = 0.0; + float pitch_scale = 0.0; + int bus_index = -1; + int reverb_bus_index = -1; AudioFrame reverb_vol[4]; - Viewport *viewport; //pointer only used for reference to previous mix - - Output() { - filter_gain = 0; - viewport = nullptr; - reverb_bus_index = -1; - bus_index = -1; - } + Viewport *viewport = nullptr; //pointer only used for reference to previous mix }; Output outputs[MAX_OUTPUTS]; - volatile int output_count; - volatile bool output_ready; + volatile int output_count = 0; + volatile bool output_ready = false; //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks) Output prev_outputs[MAX_OUTPUTS]; - int prev_output_count; + int prev_output_count = 0; Ref<AudioStreamPlayback> stream_playback; Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; - volatile float setseek; - volatile bool active; - volatile float setplay; - - AttenuationModel attenuation_model; - float unit_db; - float unit_size; - float max_db; - float pitch_scale; - bool autoplay; - bool stream_paused; - bool stream_paused_fade_in; - bool stream_paused_fade_out; + volatile float setseek = -1.0; + volatile bool active = false; + volatile float setplay = -1.0; + + AttenuationModel attenuation_model = ATTENUATION_INVERSE_DISTANCE; + float unit_db = 0.0; + float unit_size = 1.0; + float max_db = 3.0; + float pitch_scale = 1.0; + bool autoplay = false; + bool stream_paused = false; + bool stream_paused_fade_in = false; + bool stream_paused_fade_out = false; StringName bus; static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output); @@ -122,21 +115,21 @@ private: void _bus_layout_changed(); - uint32_t area_mask; + uint32_t area_mask = 1; - bool emission_angle_enabled; - float emission_angle; - float emission_angle_filter_attenuation_db; - float attenuation_filter_cutoff_hz; - float attenuation_filter_db; + bool emission_angle_enabled = false; + float emission_angle = 45.0; + float emission_angle_filter_attenuation_db = -12.0; + float attenuation_filter_cutoff_hz = 5000.0; + float attenuation_filter_db = -24.0; - float max_distance; + float max_distance = 0.0; Ref<VelocityTracker3D> velocity_tracker; - DopplerTracking doppler_tracking; + DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED; - OutOfRangeMode out_of_range_mode; + OutOfRangeMode out_of_range_mode = OUT_OF_RANGE_MIX; float _get_attenuation_db(float p_distance) const; diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 14c8755d99..75907d4a84 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -1302,7 +1302,7 @@ bool BakedLightmap::is_interior() const { void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) { environment_mode = p_mode; - _change_notify(); + notify_property_list_changed(); } BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const { @@ -1466,17 +1466,4 @@ void BakedLightmap::_bind_methods() { } BakedLightmap::BakedLightmap() { - environment_mode = ENVIRONMENT_MODE_DISABLED; - environment_custom_color = Color(0.2, 0.7, 1.0); - environment_custom_energy = 1.0; - - bake_quality = BAKE_QUALITY_MEDIUM; - interior = false; - directional = false; - - gen_probes = GENERATE_PROBES_DISABLED; - use_denoiser = true; - bounces = 1; - bias = 0.0005; - max_texture_size = 16384; } diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index 7fd1cf892e..e2d89ab2d0 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -53,9 +53,9 @@ class BakedLightmapData : public Resource { struct User { NodePath path; - int32_t sub_instance; + int32_t sub_instance = 0; Rect2 uv_scale; - int slice_index; + int slice_index = 0; }; Vector<User> users; @@ -136,32 +136,32 @@ public: }; private: - BakeQuality bake_quality; - bool use_denoiser; - int bounces; - float bias; - int max_texture_size; - bool interior; - EnvironmentMode environment_mode; + BakeQuality bake_quality = BAKE_QUALITY_MEDIUM; + bool use_denoiser = true; + int bounces = 1; + float bias = 0.0005; + int max_texture_size = 16384; + bool interior = false; + EnvironmentMode environment_mode = ENVIRONMENT_MODE_DISABLED; Ref<Sky> environment_custom_sky; - Color environment_custom_color; - float environment_custom_energy; - bool directional; - GenerateProbes gen_probes; + Color environment_custom_color = Color(0.2, 0.7, 1.0); + float environment_custom_energy = 1.0; + bool directional = false; + GenerateProbes gen_probes = GENERATE_PROBES_DISABLED; Ref<BakedLightmapData> light_data; struct LightsFound { Transform xform; - Light3D *light; + Light3D *light = nullptr; }; struct MeshesFound { Transform xform; NodePath node_path; - int32_t subindex; + int32_t subindex = 0; Ref<Mesh> mesh; - int32_t lightmap_scale; + int32_t lightmap_scale = 0; Vector<Ref<Material>> overrides; }; @@ -172,19 +172,20 @@ private: struct BakeTimeData { String text; - int pass; - uint64_t last_step; + int pass = 0; + uint64_t last_step = 0; }; struct BSPSimplex { - int vertices[4]; - int planes[4]; + int vertices[4] = {}; + int planes[4] = {}; }; struct BSPNode { static const int32_t EMPTY_LEAF = INT32_MIN; Plane plane; - int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; + int32_t over = EMPTY_LEAF; + int32_t under = EMPTY_LEAF; }; int _bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const; @@ -192,16 +193,16 @@ private: struct BakeStepUD { Lightmapper::BakeStepFunc func; - void *ud; - float from_percent; - float to_percent; + void *ud = nullptr; + float from_percent = 0.0; + float to_percent = 0.0; }; static bool _lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh); struct GenProbesOctree { Vector3i offset; - uint32_t size; + uint32_t size = 0; GenProbesOctree *children[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; ~GenProbesOctree() { for (int i = 0; i < 8; i++) { diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 30fe1ecea8..5315e685a0 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -105,7 +105,6 @@ void BoneAttachment3D::_notification(int p_what) { } BoneAttachment3D::BoneAttachment3D() { - bound = false; } void BoneAttachment3D::_bind_methods() { diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index 0dddaa1028..0c6d5f12b1 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -36,7 +36,7 @@ class BoneAttachment3D : public Node3D { GDCLASS(BoneAttachment3D, Node3D); - bool bound; + bool bound = false; String bone_name; void _check_bind(); diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 53c3204b3e..e9e93884a5 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -209,7 +209,7 @@ void Camera3D::set_projection(Camera3D::Projection p_mode) { if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) { mode = p_mode; _update_camera_mode(); - _change_notify(); + notify_property_list_changed(); } } @@ -432,7 +432,7 @@ void Camera3D::set_keep_aspect_mode(KeepAspect p_aspect) { keep_aspect = p_aspect; RenderingServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH); _update_camera_mode(); - _change_notify(); + notify_property_list_changed(); } Camera3D::KeepAspect Camera3D::get_keep_aspect_mode() const { @@ -562,14 +562,12 @@ void Camera3D::set_fov(float p_fov) { ERR_FAIL_COND(p_fov < 1 || p_fov > 179); fov = p_fov; _update_camera_mode(); - _change_notify("fov"); } void Camera3D::set_size(float p_size) { ERR_FAIL_COND(p_size < 0.1 || p_size > 16384); size = p_size; _update_camera_mode(); - _change_notify("size"); } void Camera3D::set_near(float p_near) { @@ -653,24 +651,10 @@ Vector3 Camera3D::get_doppler_tracked_velocity() const { Camera3D::Camera3D() { camera = RenderingServer::get_singleton()->camera_create(); - size = 1; - fov = 0; - frustum_offset = Vector2(); - near = 0; - far = 0; - current = false; - viewport = nullptr; - force_change = false; - mode = PROJECTION_PERSPECTIVE; set_perspective(75.0, 0.05, 4000.0); - keep_aspect = KEEP_HEIGHT; - layers = 0xfffff; - v_offset = 0; - h_offset = 0; RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers); //active=false; velocity_tracker.instance(); - doppler_tracking = DOPPLER_TRACKING_DISABLED; set_notify_transform(true); set_disable_scale(true); } @@ -882,16 +866,10 @@ void ClippedCamera3D::_bind_methods() { } ClippedCamera3D::ClippedCamera3D() { - margin = 0; - clip_offset = 0; - process_mode = CLIP_PROCESS_PHYSICS; set_physics_process_internal(true); - collision_mask = 1; set_notify_local_transform(Engine::get_singleton()->is_editor_hint()); points.resize(5); pyramid_shape = PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONVEX_POLYGON); - clip_to_areas = false; - clip_to_bodies = true; } ClippedCamera3D::~ClippedCamera3D() { diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index aa36c8800d..06bb55e23c 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -57,26 +57,27 @@ public: }; private: - bool force_change; - bool current; - Viewport *viewport; + bool force_change = false; + bool current = false; + Viewport *viewport = nullptr; - Projection mode; + Projection mode = PROJECTION_PERSPECTIVE; - float fov; - float size; + float fov = 0.0; + float size = 1.0; Vector2 frustum_offset; - float near, far; - float v_offset; - float h_offset; - KeepAspect keep_aspect; + float near = 0.0; + float far = 0.0; + float v_offset = 0.0; + float h_offset = 0.0; + KeepAspect keep_aspect = KEEP_HEIGHT; RID camera; RID scenario_id; // String camera_group; - uint32_t layers; + uint32_t layers = 0xfffff; Ref<Environment> environment; Ref<CameraEffects> effects; @@ -87,7 +88,7 @@ private: friend class Viewport; void _update_audio_listener_state(); - DopplerTracking doppler_tracking; + DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED; Ref<VelocityTracker3D> velocity_tracker; protected: @@ -191,13 +192,13 @@ public: }; private: - ProcessMode process_mode; + ProcessMode process_mode = CLIP_PROCESS_PHYSICS; RID pyramid_shape; - float margin; - float clip_offset; - uint32_t collision_mask; - bool clip_to_areas; - bool clip_to_bodies; + float margin = 0.0; + float clip_offset = 0.0; + uint32_t collision_mask = 1; + bool clip_to_areas = false; + bool clip_to_bodies = true; Set<RID> exclude; diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index f1d7ac64b2..b7da4822e2 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -325,10 +325,7 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) { rid = p_rid; area = p_area; - capture_input_on_drag = false; - ray_pickable = true; set_notify_transform(true); - total_subshapes = 0; if (p_area) { PhysicsServer3D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id()); @@ -360,8 +357,6 @@ String CollisionObject3D::get_configuration_warning() const { } CollisionObject3D::CollisionObject3D() { - capture_input_on_drag = false; - ray_pickable = true; set_notify_transform(true); //owner= diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index da65791b9c..b7473ca12a 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -37,33 +37,28 @@ class CollisionObject3D : public Node3D { GDCLASS(CollisionObject3D, Node3D); - bool area; + bool area = false; RID rid; struct ShapeData { - Object *owner; + Object *owner = nullptr; Transform xform; struct ShapeBase { Ref<Shape3D> shape; - int index; + int index = 0; }; Vector<ShapeBase> shapes; - bool disabled; - - ShapeData() { - disabled = false; - owner = nullptr; - } + bool disabled = false; }; - int total_subshapes; + int total_subshapes = 0; Map<uint32_t, ShapeData> shapes; - bool capture_input_on_drag; - bool ray_pickable; + bool capture_input_on_drag = false; + bool ray_pickable = true; void _update_pickable(); diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 5e77937533..4d117f02d3 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -132,13 +132,13 @@ AABB CollisionPolygon3D::get_item_rect() const { return aabb; } -void CollisionPolygon3D::set_depth(float p_depth) { +void CollisionPolygon3D::set_depth(real_t p_depth) { depth = p_depth; _build_polygon(); update_gizmo(); } -float CollisionPolygon3D::get_depth() const { +real_t CollisionPolygon3D::get_depth() const { return depth; } @@ -197,10 +197,5 @@ void CollisionPolygon3D::_bind_methods() { } CollisionPolygon3D::CollisionPolygon3D() { - aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); - depth = 1.0; set_notify_local_transform(true); - parent = nullptr; - owner_id = 0; - disabled = false; } diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h index ec13b9af6d..cb0aba67b1 100644 --- a/scene/3d/collision_polygon_3d.h +++ b/scene/3d/collision_polygon_3d.h @@ -39,14 +39,14 @@ class CollisionPolygon3D : public Node3D { GDCLASS(CollisionPolygon3D, Node3D); protected: - float depth; - AABB aabb; + real_t depth = 1.0; + AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); Vector<Point2> polygon; - uint32_t owner_id; - CollisionObject3D *parent; + uint32_t owner_id = 0; + CollisionObject3D *parent = nullptr; - bool disabled; + bool disabled = false; void _build_polygon(); @@ -59,8 +59,8 @@ protected: static void _bind_methods(); public: - void set_depth(float p_depth); - float get_depth() const; + void set_depth(real_t p_depth); + real_t get_depth() const; void set_polygon(const Vector<Point2> &p_polygon); Vector<Point2> get_polygon() const; diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 503d1be104..914c8eab7a 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -93,6 +93,7 @@ void CollisionShape3D::_notification(int p_what) { if (shape.is_valid()) { parent->shape_owner_add_shape(owner_id, shape); } + _update_in_shape_owner(); } } break; case NOTIFICATION_ENTER_TREE: { @@ -213,10 +214,6 @@ bool CollisionShape3D::is_disabled() const { CollisionShape3D::CollisionShape3D() { //indicator = RenderingServer::get_singleton()->mesh_create(); - disabled = false; - debug_shape = nullptr; - parent = nullptr; - owner_id = 0; set_notify_local_transform(true); } diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index 5f556b01a9..f55c09ffaa 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -40,14 +40,14 @@ class CollisionShape3D : public Node3D { Ref<Shape3D> shape; - uint32_t owner_id; - CollisionObject3D *parent; + uint32_t owner_id = 0; + CollisionObject3D *parent = nullptr; - Node *debug_shape; + Node *debug_shape = nullptr; bool debug_shape_dirty; void resource_changed(RES res); - bool disabled; + bool disabled = false; protected: void _update_debug_shape(); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 3562f7b778..7825119e6e 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -73,7 +73,7 @@ void CPUParticles3D::set_amount(int p_amount) { } particle_data.resize((12 + 4 + 4) * p_amount); - RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true); + RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true); particle_order.resize(p_amount); } @@ -372,7 +372,7 @@ void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_ena ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); particle_flags[p_particle_flag] = p_enable; if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { - _change_notify(); + notify_property_list_changed(); } } @@ -575,7 +575,7 @@ void CPUParticles3D::_particles_process(float p_delta) { cycle++; if (one_shot && cycle > 0) { set_emitting(false); - _change_notify(); + notify_property_list_changed(); } } @@ -646,6 +646,8 @@ void CPUParticles3D::_particles_process(float p_delta) { restart = true; } + float tv = 0.0; + if (restart) { if (!emitting) { p.active = false; @@ -660,12 +662,12 @@ void CPUParticles3D::_particles_process(float p_delta) { float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0); + tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv); } p.seed = Math::rand(); @@ -676,13 +678,13 @@ void CPUParticles3D::_particles_process(float p_delta) { p.anim_offset_rand = Math::randf(); if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } else { //initiate velocity spread in 3D - float angle1_rad = Math::atan2(direction.x, direction.z) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; - float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); + float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread); Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); @@ -706,8 +708,9 @@ void CPUParticles3D::_particles_process(float p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { - float s = 2.0 * Math::randf() - 1.0, t = 2.0 * Math_PI * Math::randf(); - float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); + real_t s = 2.0 * Math::randf() - 1.0; + real_t t = Math_TAU * Math::randf(); + real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s); } break; case EMISSION_SHAPE_BOX: { @@ -771,61 +774,63 @@ void CPUParticles3D::_particles_process(float p_delta) { continue; } else if (p.time > p.lifetime) { p.active = false; + tv = 1.0; } else { uint32_t alt_seed = p.seed; p.time += local_delta; p.custom[1] = p.time / lifetime; + tv = p.time / p.lifetime; float tex_linear_velocity = 0.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]); + tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv); } float tex_orbit_velocity = 0.0; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]); + tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv); } } float tex_angular_velocity = 0.0; if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { - tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]); + tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv); } float tex_linear_accel = 0.0; if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) { - tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]); + tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv); } float tex_tangential_accel = 0.0; if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { - tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]); + tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv); } float tex_radial_accel = 0.0; if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) { - tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]); + tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv); } float tex_damping = 0.0; if (curve_parameters[PARAM_DAMPING].is_valid()) { - tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]); + tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv); } float tex_angle = 0.0; if (curve_parameters[PARAM_ANGLE].is_valid()) { - tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]); + tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv); } float tex_anim_speed = 0.0; if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) { - tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]); + tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv); } float tex_anim_offset = 0.0; if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) { - tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]); + tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv); } Vector3 force = gravity; @@ -855,7 +860,7 @@ void CPUParticles3D::_particles_process(float p_delta) { if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]); if (orbit_amount != 0.0) { - float ang = orbit_amount * local_delta * Math_PI * 2.0; + float ang = orbit_amount * local_delta * Math_TAU; // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); @@ -887,15 +892,15 @@ void CPUParticles3D::_particles_process(float p_delta) { float tex_scale = 1.0; if (curve_parameters[PARAM_SCALE].is_valid()) { - tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]); + tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv); } float tex_hue_variation = 0.0; if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) { - tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]); + tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv); } - float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); + float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]); float hue_rot_c = Math::cos(hue_rot_angle); float hue_rot_s = Math::sin(hue_rot_angle); @@ -911,7 +916,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } if (color_ramp.is_valid()) { - p.color = color_ramp->get_color_at_offset(p.custom[1]) * color; + p.color = color_ramp->get_color_at_offset(tv) * color; } else { p.color = color; } @@ -1440,13 +1445,6 @@ void CPUParticles3D::_bind_methods() { } CPUParticles3D::CPUParticles3D() { - time = 0; - inactive_time = 0; - frame_remainder = 0; - cycle = 0; - redraw = false; - emitting = false; - set_notify_transform(true); multimesh = RenderingServer::get_singleton()->multimesh_create(); @@ -1454,23 +1452,8 @@ CPUParticles3D::CPUParticles3D() { set_base(multimesh); set_emitting(true); - set_one_shot(false); set_amount(8); - set_lifetime(1); - set_fixed_fps(0); - set_fractional_delta(true); - set_pre_process_time(0); - set_explosiveness_ratio(0); - set_randomness_ratio(0); - set_lifetime_randomness(0); - set_use_local_coordinates(true); - - set_draw_order(DRAW_ORDER_INDEX); - set_speed_scale(1); - - set_direction(Vector3(1, 0, 0)); - set_spread(45); - set_flatness(0); + set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); set_param(PARAM_ANGULAR_VELOCITY, 0); set_param(PARAM_ORBIT_VELOCITY, 0); @@ -1483,23 +1466,6 @@ CPUParticles3D::CPUParticles3D() { set_param(PARAM_HUE_VARIATION, 0); set_param(PARAM_ANIM_SPEED, 0); set_param(PARAM_ANIM_OFFSET, 0); - set_emission_shape(EMISSION_SHAPE_POINT); - set_emission_sphere_radius(1); - set_emission_box_extents(Vector3(1, 1, 1)); - - set_gravity(Vector3(0, -9.8, 0)); - - for (int i = 0; i < PARAM_MAX; i++) { - set_param_randomness(Parameter(i), 0); - } - - for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { - particle_flags[i] = false; - } - - can_update = false; - - set_color(Color(1, 1, 1, 1)); } CPUParticles3D::~CPUParticles3D() { diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 3ee03ff3d8..d650bf95ac 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -78,30 +78,30 @@ public: }; private: - bool emitting; + bool emitting = false; struct Particle { Transform transform; Color color; - float custom[4]; + float custom[4] = {}; Vector3 velocity; - bool active; - float angle_rand; - float scale_rand; - float hue_rot_rand; - float anim_offset_rand; - float time; - float lifetime; + bool active = false; + float angle_rand = 0.0; + float scale_rand = 0.0; + float hue_rot_rand = 0.0; + float anim_offset_rand = 0.0; + float time = 0.0; + float lifetime = 0.0; Color base_color; - uint32_t seed; + uint32_t seed = 0; }; - float time; - float inactive_time; - float frame_remainder; - int cycle; - bool redraw; + float time = 0.0; + float inactive_time = 0.0; + float frame_remainder = 0.0; + int cycle = 0; + bool redraw = false; RID multimesh; @@ -110,7 +110,7 @@ private: Vector<int> particle_order; struct SortLifetime { - const Particle *particles; + const Particle *particles = nullptr; bool operator()(int p_a, int p_b) const { return particles[p_a].time > particles[p_b].time; @@ -118,7 +118,7 @@ private: }; struct SortAxis { - const Particle *particles; + const Particle *particles = nullptr; Vector3 axis; bool operator()(int p_a, int p_b) const { return axis.dot(particles[p_a].transform.origin) < axis.dot(particles[p_b].transform.origin); @@ -127,50 +127,50 @@ private: // - bool one_shot; + bool one_shot = false; - float lifetime; - float pre_process_time; - float explosiveness_ratio; - float randomness_ratio; - float lifetime_randomness; - float speed_scale; - bool local_coords; - int fixed_fps; - bool fractional_delta; + float lifetime = 1.0; + float pre_process_time = 0.0; + float explosiveness_ratio = 0.0; + float randomness_ratio = 0.0; + float lifetime_randomness = 0.0; + float speed_scale = 1.0; + bool local_coords = true; + int fixed_fps = 0; + bool fractional_delta = true; Transform inv_emission_transform; - volatile bool can_update; + volatile bool can_update = false; - DrawOrder draw_order; + DrawOrder draw_order = DRAW_ORDER_INDEX; Ref<Mesh> mesh; //////// - Vector3 direction; - float spread; - float flatness; + Vector3 direction = Vector3(1, 0, 0); + float spread = 45.0; + float flatness = 0.0; float parameters[PARAM_MAX]; - float randomness[PARAM_MAX]; + float randomness[PARAM_MAX] = {}; Ref<Curve> curve_parameters[PARAM_MAX]; - Color color; + Color color = Color(1, 1, 1, 1); Ref<Gradient> color_ramp; - bool particle_flags[PARTICLE_FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX] = {}; - EmissionShape emission_shape; - float emission_sphere_radius; - Vector3 emission_box_extents; + EmissionShape emission_shape = EMISSION_SHAPE_POINT; + float emission_sphere_radius = 1.0; + Vector3 emission_box_extents = Vector3(1, 1, 1); Vector<Vector3> emission_points; Vector<Vector3> emission_normals; Vector<Color> emission_colors; - int emission_point_count; + int emission_point_count = 0; - Vector3 gravity; + Vector3 gravity = Vector3(0, -9.8, 0); void _update_internal(); void _particles_process(float p_delta); diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index e67802cfc4..0f10f2b85f 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -34,7 +34,6 @@ void Decal::set_extents(const Vector3 &p_extents) { extents = p_extents; RS::get_singleton()->decal_set_extents(decal, p_extents); update_gizmo(); - _change_notify("extents"); } Vector3 Decal::get_extents() const { @@ -220,18 +219,6 @@ void Decal::_bind_methods() { } Decal::Decal() { - extents = Vector3(1, 1, 1); - emission_energy = 1.0; - modulate = Color(1, 1, 1, 1); - albedo_mix = 1.0; - cull_mask = (1 << 20) - 1; - upper_fade = 0.3; - lower_fade = 0.3; - normal_fade = 0; - distance_fade_enabled = false; - distance_fade_begin = 10; - distance_fade_length = 1; - decal = RenderingServer::get_singleton()->decal_create(); RS::get_singleton()->instance_set_base(get_instance(), decal); } diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 500a1425f2..095579d775 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -49,18 +49,18 @@ public: private: RID decal; - Vector3 extents; + Vector3 extents = Vector3(1, 1, 1); Ref<Texture2D> textures[TEXTURE_MAX]; - float emission_energy; - float albedo_mix; - Color modulate; - uint32_t cull_mask; - float normal_fade; - float upper_fade; - float lower_fade; - bool distance_fade_enabled; - float distance_fade_begin; - float distance_fade_length; + float emission_energy = 1.0; + float albedo_mix = 1.0; + Color modulate = Color(1, 1, 1, 1); + uint32_t cull_mask = (1 << 20) - 1; + float normal_fade = 0.0; + float upper_fade = 0.3; + float lower_fade = 0.3; + bool distance_fade_enabled = false; + float distance_fade_begin = 10.0; + float distance_fade_length = 1.0; protected: static void _bind_methods(); diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 0565193437..942996ca14 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -91,7 +91,7 @@ Dictionary GIProbeData::_get_data() const { } void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { - RS::get_singleton()->gi_probe_allocate(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); + RS::get_singleton()->gi_probe_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); bounds = p_aabb; to_cell_xform = p_to_cell_xform; octree_size = p_octree_size; @@ -286,17 +286,6 @@ void GIProbeData::_bind_methods() { } GIProbeData::GIProbeData() { - ao = 0.0; - ao_size = 0.5; - dynamic_range = 4; - energy = 1.0; - bias = 1.5; - normal_bias = 0.0; - propagation = 0.7; - anisotropy_strength = 0.5; - interior = false; - use_two_bounces = false; - probe = RS::get_singleton()->gi_probe_create(); } @@ -334,7 +323,6 @@ GIProbe::Subdiv GIProbe::get_subdiv() const { void GIProbe::set_extents(const Vector3 &p_extents) { extents = p_extents; update_gizmo(); - _change_notify("extents"); } Vector3 GIProbe::get_extents() const { @@ -497,7 +485,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { bake_end_function(); } - _change_notify(); //bake property may have changed + notify_property_list_changed(); //bake property may have changed } void GIProbe::_debug_bake() { @@ -553,9 +541,6 @@ void GIProbe::_bind_methods() { } GIProbe::GIProbe() { - subdiv = SUBDIV_128; - extents = Vector3(10, 10, 10); - gi_probe = RS::get_singleton()->gi_probe_create(); set_disable_scale(true); } diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index afea94fe12..534b425557 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -46,16 +46,16 @@ class GIProbeData : public Resource { AABB bounds; Vector3 octree_size; - float dynamic_range; - float energy; - float bias; - float normal_bias; - float propagation; - float anisotropy_strength; - float ao; - float ao_size; - bool interior; - bool use_two_bounces; + float dynamic_range = 4.0; + float energy = 1.0; + float bias = 1.5; + float normal_bias = 0.0; + float propagation = 0.7; + float anisotropy_strength = 0.5; + float ao = 0.0; + float ao_size = 0.5; + bool interior = false; + bool use_two_bounces = false; protected: static void _bind_methods(); @@ -129,8 +129,8 @@ private: RID gi_probe; - Subdiv subdiv; - Vector3 extents; + Subdiv subdiv = SUBDIV_128; + Vector3 extents = Vector3(10, 10, 10); struct PlotMesh { Ref<Material> override_material; diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 7d77578b01..17a61b3e4d 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -100,7 +100,6 @@ void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) { visibility_aabb = p_aabb; RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb); update_gizmo(); - _change_notify("visibility_aabb"); } void GPUParticles3D::set_use_local_coordinates(bool p_enable) { @@ -190,7 +189,7 @@ void GPUParticles3D::set_draw_passes(int p_count) { ERR_FAIL_COND(p_count < 1); draw_passes.resize(p_count); RS::get_singleton()->particles_set_draw_passes(particles, p_count); - _change_notify(); + notify_property_list_changed(); } int GPUParticles3D::get_draw_passes() const { @@ -353,7 +352,7 @@ void GPUParticles3D::_notification(int p_what) { // the shot ends the editor can properly update if (p_what == NOTIFICATION_INTERNAL_PROCESS) { if (one_shot && !is_emitting()) { - _change_notify(); + notify_property_list_changed(); set_process_internal(false); } } diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 7d6301ee50..81c33663f3 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -130,16 +130,16 @@ private: LEAF_MASK = LEAF_BIT - 1 }; AABB bounds; - uint32_t children[2]; + uint32_t children[2] = {}; }; struct FacePos { Vector3 center; - uint32_t index; + uint32_t index = 0; }; struct FaceSort { - uint32_t axis; + uint32_t axis = 0; bool operator()(const FacePos &p_left, const FacePos &p_right) const { return p_left.center[axis] < p_right.center[axis]; } @@ -148,13 +148,13 @@ private: uint32_t _create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness); struct ComputeSDFParams { - float *cells; + float *cells = nullptr; Vector3i size; - float cell_size; + float cell_size = 0.0; Vector3 cell_offset; - const BVH *bvh; - const Face3 *triangles; - float thickness; + const BVH *bvh = nullptr; + const Face3 *triangles = nullptr; + float thickness = 0.0; }; void _find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance); diff --git a/scene/3d/immediate_geometry_3d.cpp b/scene/3d/immediate_geometry_3d.cpp index 17410d5870..d64babaa9d 100644 --- a/scene/3d/immediate_geometry_3d.cpp +++ b/scene/3d/immediate_geometry_3d.cpp @@ -87,21 +87,24 @@ Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const { } void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) { + const double lat_step = Math_TAU / p_lats; + const double lon_step = Math_TAU / p_lons; + for (int i = 1; i <= p_lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / p_lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = p_lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / p_lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); @@ -147,7 +150,6 @@ void ImmediateGeometry3D::_bind_methods() { ImmediateGeometry3D::ImmediateGeometry3D() { im = RenderingServer::get_singleton()->immediate_create(); set_base(im); - empty = true; } ImmediateGeometry3D::~ImmediateGeometry3D() { diff --git a/scene/3d/immediate_geometry_3d.h b/scene/3d/immediate_geometry_3d.h index 8e546e27e7..ee4938d9f7 100644 --- a/scene/3d/immediate_geometry_3d.h +++ b/scene/3d/immediate_geometry_3d.h @@ -41,7 +41,7 @@ class ImmediateGeometry3D : public GeometryInstance3D { //a list of textures drawn need to be kept, to avoid references // in RenderingServer from becoming invalid if the texture is no longer used List<Ref<Texture2D>> cached_textures; - bool empty; + bool empty = true; AABB aabb; protected: diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index b998a1a400..b0a10b5547 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -48,11 +48,7 @@ void Light3D::set_param(Param p_param, float p_value) { update_gizmo(); if (p_param == PARAM_SPOT_ANGLE) { - _change_notify("spot_angle"); update_configuration_warning(); - } else if (p_param == PARAM_RANGE) { - _change_notify("omni_range"); - _change_notify("spot_range"); } } } @@ -184,8 +180,6 @@ void Light3D::_update_visibility() { #endif RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree() && editor_ok); - - _change_notify("geometry/visible"); } void Light3D::_notification(int p_what) { @@ -324,10 +318,6 @@ Light3D::Light3D(RenderingServer::LightType p_type) { RS::get_singleton()->instance_set_base(get_instance(), light); - reverse_cull = false; - bake_mode = BAKE_DYNAMIC; - - editor_only = false; set_color(Color(1, 1, 1, 1)); set_shadow(false); set_negative(false); @@ -351,13 +341,12 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_BIAS, 0.02); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); - set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 1.0); + set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1); set_param(PARAM_SHADOW_FADE_START, 1); set_disable_scale(true); } Light3D::Light3D() { - type = RenderingServer::LIGHT_DIRECTIONAL; ERR_PRINT("Light3D should not be instanced directly; use the DirectionalLight3D, OmniLight3D or SpotLight3D subtypes instead."); } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 833598c4a1..311db54bce 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -71,16 +71,16 @@ public: private: Color color; - float param[PARAM_MAX]; + float param[PARAM_MAX] = {}; Color shadow_color; - bool shadow; - bool negative; - bool reverse_cull; - uint32_t cull_mask; - RS::LightType type; - bool editor_only; + bool shadow = false; + bool negative = false; + bool reverse_cull = false; + uint32_t cull_mask = 0; + RS::LightType type = RenderingServer::LIGHT_DIRECTIONAL; + bool editor_only = false; void _update_visibility(); - BakeMode bake_mode; + BakeMode bake_mode = BAKE_DYNAMIC; Ref<Texture2D> projector; // bind helpers diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp index 23adb0aa19..9842f152d7 100644 --- a/scene/3d/listener_3d.cpp +++ b/scene/3d/listener_3d.cpp @@ -159,8 +159,6 @@ void Listener3D::_bind_methods() { } Listener3D::Listener3D() { - current = false; - force_change = false; set_notify_transform(true); //active=false; } diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h index 2a78efb2c7..85657a8e53 100644 --- a/scene/3d/listener_3d.h +++ b/scene/3d/listener_3d.h @@ -38,8 +38,8 @@ class Listener3D : public Node3D { GDCLASS(Listener3D, Node3D); private: - bool force_change; - bool current; + bool force_change = false; + bool current = false; RID scenario_id; diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 44dd6e0e5f..7b3a0820f1 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -95,7 +95,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { ls.sort(); for (List<String>::Element *E = ls.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "0,1,0.00001")); + p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "-1,1,0.00001")); } if (mesh.is_valid()) { @@ -135,7 +135,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) { update_gizmo(); - _change_notify(); + notify_property_list_changed(); } Ref<Mesh> MeshInstance3D::get_mesh() const { @@ -152,7 +152,7 @@ void MeshInstance3D::_resolve_skeleton_path() { if (skin_internal.is_null()) { //a skin was created for us skin_internal = new_skin_reference->get_skin(); - _change_notify(); + notify_property_list_changed(); } } } @@ -428,7 +428,6 @@ void MeshInstance3D::_bind_methods() { } MeshInstance3D::MeshInstance3D() { - skeleton_path = NodePath(".."); } MeshInstance3D::~MeshInstance3D() { diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index 822e04e656..eb300784b1 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -44,15 +44,11 @@ protected: Ref<Skin> skin; Ref<Skin> skin_internal; Ref<SkinReference> skin_ref; - NodePath skeleton_path; + NodePath skeleton_path = NodePath(".."); struct BlendShapeTrack { - int idx; - float value; - BlendShapeTrack() { - idx = 0; - value = 0; - } + int idx = 0; + float value = 0.0; }; Map<StringName, BlendShapeTrack> blend_shape_tracks; diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp index 2a7195be1a..eaddec7601 100644 --- a/scene/3d/navigation_3d.cpp +++ b/scene/3d/navigation_3d.cpp @@ -110,8 +110,6 @@ Navigation3D::Navigation3D() { set_cell_size(0.3); set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius - - up = Vector3(0, 1, 0); } Navigation3D::~Navigation3D() { diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h index 3e8adaf5ff..b89725a3f5 100644 --- a/scene/3d/navigation_3d.h +++ b/scene/3d/navigation_3d.h @@ -39,7 +39,7 @@ class Navigation3D : public Node3D { RID map; - Vector3 up; + Vector3 up = Vector3(0, 1, 0); real_t cell_size; real_t edge_connection_margin; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index e8cfa05a4b..19bde94222 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -124,13 +124,13 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes } if (navmesh.is_valid()) { - navmesh->remove_change_receptor(this); + navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } navmesh = p_navmesh; if (navmesh.is_valid()) { - navmesh->add_change_receptor(this); + navmesh->connect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } NavigationServer3D::get_singleton()->region_set_navmesh(region, p_navmesh); @@ -150,7 +150,7 @@ Ref<NavigationMesh> NavigationRegion3D::get_navigation_mesh() const { } struct BakeThreadsArgs { - NavigationRegion3D *nav_region; + NavigationRegion3D *nav_region = nullptr; }; void _bake_navigation_mesh(void *p_user_data) { @@ -230,7 +230,7 @@ void NavigationRegion3D::_bind_methods() { ADD_SIGNAL(MethodInfo("bake_finished")); } -void NavigationRegion3D::_changed_callback(Object *p_changed, const char *p_prop) { +void NavigationRegion3D::_navigation_changed() { update_gizmo(); update_configuration_warning(); } @@ -242,7 +242,7 @@ NavigationRegion3D::NavigationRegion3D() { NavigationRegion3D::~NavigationRegion3D() { if (navmesh.is_valid()) { - navmesh->remove_change_receptor(this); + navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed)); } NavigationServer3D::get_singleton()->free(region); } diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index e966523b64..6ae15c9360 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -48,10 +48,11 @@ class NavigationRegion3D : public Node3D { Node *debug_view = nullptr; Thread bake_thread; + void _navigation_changed(); + protected: void _notification(int p_what); static void _bind_methods(); - void _changed_callback(Object *p_changed, const char *p_prop) override; public: void set_enabled(bool p_enabled); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 2a49e60669..3b1fb830e3 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -226,10 +226,6 @@ void Node3D::_notification(int p_what) { void Node3D::set_transform(const Transform &p_transform) { data.local_transform = p_transform; data.dirty |= DIRTY_VECTORS; - _change_notify("translation"); - _change_notify("rotation"); - _change_notify("rotation_degrees"); - _change_notify("scale"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -307,7 +303,6 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const { void Node3D::set_translation(const Vector3 &p_translation) { data.local_transform.origin = p_translation; - _change_notify("transform"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -322,7 +317,6 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) { data.rotation = p_euler_rad; data.dirty |= DIRTY_LOCAL; - _change_notify("transform"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -330,7 +324,7 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) { } void Node3D::set_rotation_degrees(const Vector3 &p_euler_deg) { - set_rotation(p_euler_deg * Math_PI / 180.0); + set_rotation(p_euler_deg * (Math_PI / 180.0)); } void Node3D::set_scale(const Vector3 &p_scale) { @@ -341,7 +335,6 @@ void Node3D::set_scale(const Vector3 &p_scale) { data.scale = p_scale; data.dirty |= DIRTY_LOCAL; - _change_notify("transform"); _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -364,7 +357,7 @@ Vector3 Node3D::get_rotation() const { } Vector3 Node3D::get_rotation_degrees() const { - return get_rotation() * 180.0 / Math_PI; + return get_rotation() * (180.0 / Math_PI); } Vector3 Node3D::get_scale() const { @@ -495,7 +488,6 @@ Ref<World3D> Node3D::get_world_3d() const { void Node3D::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringNames::get_singleton()->visibility_changed); - _change_notify("visible"); #ifdef TOOLS_ENABLED if (data.gizmo.is_valid()) { _update_gizmo(); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 3f048beb71..7e2601902b 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -323,8 +323,6 @@ void PathFollow3D::set_offset(float p_offset) { _update_transform(); } - _change_notify("offset"); - _change_notify("unit_offset"); } void PathFollow3D::set_h_offset(float p_h_offset) { diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 15e38c95e7..17ee47593e 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -66,10 +66,10 @@ public: private: Path3D *path = nullptr; - real_t delta_offset = 0; // Change in offset since last _update_transform. - real_t offset = 0; - real_t h_offset = 0; - real_t v_offset = 0; + real_t delta_offset = 0.0; // Change in offset since last _update_transform. + real_t offset = 0.0; + real_t h_offset = 0.0; + real_t v_offset = 0.0; bool cubic = true; bool loop = true; RotationMode rotation_mode = ROTATION_XYZ; diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 4d712069ec..6d135c8283 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -51,7 +51,7 @@ Vector3 PhysicsBody3D::get_angular_velocity() const { return Vector3(); } -float PhysicsBody3D::get_inverse_mass() const { +real_t PhysicsBody3D::get_inverse_mass() const { return 0; } @@ -148,7 +148,8 @@ void PhysicsBody3D::_bind_methods() { } PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : - CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(p_mode), false) { + CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); collision_layer = 1; collision_mask = 1; } @@ -330,8 +331,8 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap struct _RigidBodyInOut { ObjectID id; - int shape; - int local_shape; + int shape = 0; + int local_shape = 0; }; void RigidBody3D::_direct_state_changed(Object *p_state) { @@ -825,24 +826,6 @@ void RigidBody3D::_bind_methods() { RigidBody3D::RigidBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { - mode = MODE_RIGID; - - mass = 1; - max_contacts_reported = 0; - state = nullptr; - - gravity_scale = 1; - linear_damp = -1; - angular_damp = -1; - - //angular_velocity=0; - sleeping = false; - ccd = false; - - custom_integrator = false; - contact_monitor = nullptr; - can_sleep = true; - PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -924,7 +907,7 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_ //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector3 body_velocity = p_linear_velocity; Vector3 body_velocity_normal = body_velocity.normalized(); Vector3 up_direction = p_up_direction.normalized(); @@ -1018,7 +1001,7 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const return body_velocity; } -Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { +Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { Vector3 up_direction = p_up_direction.normalized(); bool was_on_floor = on_floor; @@ -1090,7 +1073,7 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision Vector3 recover; int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; - float deepest_depth; + real_t deepest_depth; for (int i = 0; i < hits; i++) { if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) { deepest = i; @@ -1131,12 +1114,12 @@ bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); } -void KinematicBody3D::set_safe_margin(float p_margin) { +void KinematicBody3D::set_safe_margin(real_t p_margin) { margin = p_margin; PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); } -float KinematicBody3D::get_safe_margin() const { +real_t KinematicBody3D::get_safe_margin() const { return margin; } @@ -1180,8 +1163,8 @@ void KinematicBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody3D::_direct_state_changed); ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true)); @@ -1221,11 +1204,6 @@ void KinematicBody3D::_direct_state_changed(Object *p_state) { KinematicBody3D::KinematicBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { - locked_axis = 0; - on_floor = false; - on_ceiling = false; - on_wall = false; - set_safe_margin(0.001); PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } @@ -2034,7 +2012,7 @@ void PhysicalBone3D::_notification(int p_what) { update_bone_id(); reset_to_rest_position(); reset_physics_simulation_state(); - if (!joint.is_valid() && joint_data) { + if (joint_data) { _reload_joint(); } break; @@ -2045,10 +2023,7 @@ void PhysicalBone3D::_notification(int p_what) { } } parent_skeleton = nullptr; - if (joint.is_valid()) { - PhysicsServer3D::get_singleton()->free(joint); - joint = RID(); - } + PhysicsServer3D::get_singleton()->joint_clear(joint); break; case NOTIFICATION_TRANSFORM_CHANGED: if (Engine::get_singleton()->is_editor_hint()) { @@ -2198,17 +2173,14 @@ void PhysicalBone3D::_fix_joint_offset() { } void PhysicalBone3D::_reload_joint() { - if (joint.is_valid()) { - PhysicsServer3D::get_singleton()->free(joint); - joint = RID(); - } - if (!parent_skeleton) { + PhysicsServer3D::get_singleton()->joint_clear(joint); return; } PhysicalBone3D *body_a = parent_skeleton->get_physical_bone_parent(bone_id); if (!body_a) { + PhysicsServer3D::get_singleton()->joint_clear(joint); return; } @@ -2218,7 +2190,7 @@ void PhysicalBone3D::_reload_joint() { switch (get_joint_type()) { case JOINT_TYPE_PIN: { - joint = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin); + PhysicsServer3D::get_singleton()->joint_make_pin(joint, body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin); const PinJointData *pjd(static_cast<const PinJointData *>(joint_data)); PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias); PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_DAMPING, pjd->damping); @@ -2226,7 +2198,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_CONE: { - joint = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_cone_twist(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data)); PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span); PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, cjd->twist_span); @@ -2236,7 +2208,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_HINGE: { - joint = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_hinge(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data)); PhysicsServer3D::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled); PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, hjd->angular_limit_upper); @@ -2247,7 +2219,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_SLIDER: { - joint = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_slider(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data)); PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper); PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER, sjd->linear_limit_lower); @@ -2262,7 +2234,7 @@ void PhysicalBone3D::_reload_joint() { } break; case JOINT_TYPE_6DOF: { - joint = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset); + PhysicsServer3D::get_singleton()->joint_make_generic_6dof(joint, body_a->get_rid(), local_a, get_rid(), joint_offset); const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data)); for (int axis = 0; axis < 3; ++axis) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, g6dofjd->axis_data[axis].linear_limit_enabled); @@ -2355,7 +2327,7 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) { _reload_joint(); #ifdef TOOLS_ENABLED - _change_notify(); + notify_property_list_changed(); if (get_gizmo().is_valid()) { get_gizmo()->redraw(); } @@ -2370,7 +2342,6 @@ void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; _update_joint_offset(); - _change_notify("joint_rotation_degrees"); } const Transform &PhysicalBone3D::get_joint_offset() const { @@ -2381,7 +2352,6 @@ void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); _update_joint_offset(); - _change_notify("joint_offset"); } Vector3 PhysicalBone3D::get_joint_rotation() const { @@ -2389,11 +2359,11 @@ Vector3 PhysicalBone3D::get_joint_rotation() const { } void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { - set_joint_rotation(p_euler_deg * Math_PI / 180.0); + set_joint_rotation(p_euler_deg * (Math_PI / 180.0)); } Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { - return get_joint_rotation() * 180.0 / Math_PI; + return get_joint_rotation() * (180.0 / Math_PI); } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2516,6 +2486,7 @@ bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { + joint = PhysicsServer3D::get_singleton()->joint_create(); reset_physics_simulation_state(); } @@ -2523,6 +2494,7 @@ PhysicalBone3D::~PhysicalBone3D() { if (joint_data) { memdelete(joint_data); } + PhysicsServer3D::get_singleton()->free(joint); } void PhysicalBone3D::update_bone_id() { diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index d9b95e6551..1450fce6a6 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -50,7 +50,7 @@ protected: public: virtual Vector3 get_linear_velocity() const; virtual Vector3 get_angular_velocity() const; - virtual float get_inverse_mass() const; + virtual real_t get_inverse_mass() const; void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; @@ -111,31 +111,31 @@ public: }; protected: - bool can_sleep; - PhysicsDirectBodyState3D *state; - Mode mode; + bool can_sleep = true; + PhysicsDirectBodyState3D *state = nullptr; + Mode mode = MODE_RIGID; - real_t mass; + real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; Vector3 linear_velocity; Vector3 angular_velocity; Basis inverse_inertia_tensor; - real_t gravity_scale; - real_t linear_damp; - real_t angular_damp; + real_t gravity_scale = 1.0; + real_t linear_damp = -1.0; + real_t angular_damp = -1.0; - bool sleeping; - bool ccd; + bool sleeping = false; + bool ccd = false; - int max_contacts_reported; + int max_contacts_reported = 0; - bool custom_integrator; + bool custom_integrator = false; struct ShapePair { - int body_shape; - int local_shape; - bool tagged; + int body_shape = 0; + int local_shape = 0; + bool tagged = false; bool operator<(const ShapePair &p_sp) const { if (body_shape == p_sp.body_shape) { return local_shape < p_sp.local_shape; @@ -157,16 +157,16 @@ protected: }; struct BodyState { //int rc; - bool in_tree; + bool in_tree = false; VSet<ShapePair> shapes; }; struct ContactMonitor { - bool locked; + bool locked = false; Map<ObjectID, BodyState> body_map; }; - ContactMonitor *contact_monitor; + ContactMonitor *contact_monitor = nullptr; void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); @@ -183,7 +183,7 @@ public: void set_mass(real_t p_mass); real_t get_mass() const; - virtual float get_inverse_mass() const override { return 1.0 / mass; } + virtual real_t get_inverse_mass() const override { return 1.0 / mass; } void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -261,27 +261,27 @@ public: Vector3 collider_vel; ObjectID collider; RID collider_rid; - int collider_shape; + int collider_shape = 0; Variant collider_metadata; Vector3 remainder; Vector3 travel; - int local_shape; + int local_shape = 0; }; private: Vector3 linear_velocity; Vector3 angular_velocity; - uint16_t locked_axis; + uint16_t locked_axis = 0; - float margin; + real_t margin; Vector3 floor_normal; Vector3 floor_velocity; RID on_floor_body; - bool on_floor; - bool on_ceiling; - bool on_wall; + bool on_floor = false; + bool on_ceiling = false; + bool on_wall = false; Vector<Collision> colliders; Vector<Ref<KinematicCollision3D>> slide_colliders; Ref<KinematicCollision3D> motion_cache; @@ -309,11 +309,11 @@ public: void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; - void set_safe_margin(float p_margin); - float get_safe_margin() const; + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); - Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true); + Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); + Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; @@ -385,10 +385,8 @@ public: virtual void _get_property_list(List<PropertyInfo> *p_list) const; real_t bias = 0.3; - real_t damping = 1.; - real_t impulse_clamp = 0; - - PinJointData() {} + real_t damping = 1.0; + real_t impulse_clamp = 0.0; }; struct ConeJointData : public JointData { @@ -398,14 +396,11 @@ public: virtual bool _get(const StringName &p_name, Variant &r_ret) const; virtual void _get_property_list(List<PropertyInfo> *p_list) const; - real_t swing_span; + real_t swing_span = Math_PI * 0.25; real_t twist_span = Math_PI; real_t bias = 0.3; real_t softness = 0.8; real_t relaxation = 1.; - - ConeJointData() : - swing_span(Math_PI * 0.25) {} }; struct HingeJointData : public JointData { @@ -416,16 +411,11 @@ public: virtual void _get_property_list(List<PropertyInfo> *p_list) const; bool angular_limit_enabled = false; - real_t angular_limit_upper; - real_t angular_limit_lower; + real_t angular_limit_upper = Math_PI * 0.5; + real_t angular_limit_lower = -Math_PI * 0.5; real_t angular_limit_bias = 0.3; real_t angular_limit_softness = 0.9; real_t angular_limit_relaxation = 1.; - - HingeJointData() : - - angular_limit_upper(Math_PI * 0.5), - angular_limit_lower(-Math_PI * 0.5) {} }; struct SliderJointData : public JointData { @@ -435,45 +425,41 @@ public: virtual bool _get(const StringName &p_name, Variant &r_ret) const; virtual void _get_property_list(List<PropertyInfo> *p_list) const; - real_t linear_limit_upper = 1.; - real_t linear_limit_lower = -1.; - real_t linear_limit_softness = 1.; + real_t linear_limit_upper = 1.0; + real_t linear_limit_lower = -1.0; + real_t linear_limit_softness = 1.0; real_t linear_limit_restitution = 0.7; - real_t linear_limit_damping = 1.; - real_t angular_limit_upper = 0; - real_t angular_limit_lower = 0; - real_t angular_limit_softness = 1.; + real_t linear_limit_damping = 1.0; + real_t angular_limit_upper = 0.0; + real_t angular_limit_lower = 0.0; + real_t angular_limit_softness = 1.0; real_t angular_limit_restitution = 0.7; - real_t angular_limit_damping = 1.; - - SliderJointData() {} + real_t angular_limit_damping = 1.0; }; struct SixDOFJointData : public JointData { struct SixDOFAxisData { bool linear_limit_enabled = true; - real_t linear_limit_upper = 0; - real_t linear_limit_lower = 0; + real_t linear_limit_upper = 0.0; + real_t linear_limit_lower = 0.0; real_t linear_limit_softness = 0.7; real_t linear_restitution = 0.5; - real_t linear_damping = 1.; + real_t linear_damping = 1.0; bool linear_spring_enabled = false; - real_t linear_spring_stiffness = 0; - real_t linear_spring_damping = 0; - real_t linear_equilibrium_point = 0; + real_t linear_spring_stiffness = 0.0; + real_t linear_spring_damping = 0.0; + real_t linear_equilibrium_point = 0.0; bool angular_limit_enabled = true; - real_t angular_limit_upper = 0; - real_t angular_limit_lower = 0; + real_t angular_limit_upper = 0.0; + real_t angular_limit_lower = 0.0; real_t angular_limit_softness = 0.5; - real_t angular_restitution = 0; - real_t angular_damping = 1.; + real_t angular_restitution = 0.0; + real_t angular_damping = 1.0; real_t erp = 0.5; bool angular_spring_enabled = false; - real_t angular_spring_stiffness = 0; - real_t angular_spring_damping = 0.; - real_t angular_equilibrium_point = 0; - - SixDOFAxisData() {} + real_t angular_spring_stiffness = 0.0; + real_t angular_spring_damping = 0.0; + real_t angular_equilibrium_point = 0.0; }; virtual JointType get_joint_type() { return JOINT_TYPE_6DOF; } @@ -505,12 +491,12 @@ private: int bone_id = -1; String bone_name; - real_t bounce = 0; - real_t mass = 1; - real_t friction = 1; - real_t gravity_scale = 1; - real_t linear_damp = -1; - real_t angular_damp = -1; + real_t bounce = 0.0; + real_t mass = 1.0; + real_t friction = 1.0; + real_t gravity_scale = 1.0; + real_t linear_damp = -1.0; + real_t angular_damp = -1.0; bool can_sleep = true; protected: diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 326b91b6ed..0463bed9d6 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -62,18 +62,17 @@ void Joint3D::_body_exit_tree(const ObjectID &p_body_id) { } void Joint3D::_update_joint(bool p_only_free) { - if (joint.is_valid()) { - if (ba.is_valid() && bb.is_valid()) { - PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb); - } - - PhysicsServer3D::get_singleton()->free(joint); - joint = RID(); - ba = RID(); - bb = RID(); + if (ba.is_valid() && bb.is_valid()) { + PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb); } + ba = RID(); + bb = RID(); + + configured = false; + if (p_only_free || !is_inside_tree()) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = String(); return; } @@ -85,30 +84,35 @@ void Joint3D::_update_joint(bool p_only_free) { PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b); if (node_a && !body_a && node_b && !body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be PhysicsBody3Ds"); update_configuration_warning(); return; } if (node_a && !body_a) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node A must be a PhysicsBody3D"); update_configuration_warning(); return; } if (node_b && !body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node B must be a PhysicsBody3D"); update_configuration_warning(); return; } if (!body_a && !body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Joint is not connected to any PhysicsBody3Ds"); update_configuration_warning(); return; } if (body_a == body_b) { + PhysicsServer3D::get_singleton()->joint_clear(joint); warning = TTR("Node A and Node B must be different PhysicsBody3Ds"); update_configuration_warning(); return; @@ -117,14 +121,14 @@ void Joint3D::_update_joint(bool p_only_free) { warning = String(); update_configuration_warning(); + configured = true; + if (body_a) { - joint = _configure_joint(body_a, body_b); + _configure_joint(joint, body_a, body_b); } else if (body_b) { - joint = _configure_joint(body_b, nullptr); + _configure_joint(joint, body_b, nullptr); } - ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint."); - PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority); if (body_a) { @@ -245,9 +249,12 @@ void Joint3D::_bind_methods() { } Joint3D::Joint3D() { - exclude_from_collision = true; - solver_priority = 1; set_notify_transform(true); + joint = PhysicsServer3D::get_singleton()->joint_create(); +} + +Joint3D::~Joint3D() { + PhysicsServer3D::get_singleton()->free(joint); } /////////////////////////////////// @@ -265,20 +272,20 @@ void PinJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_IMPULSE_CLAMP); } -void PinJoint3D::set_param(Param p_param, float p_value) { +void PinJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, 3); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer3D::PinJointParam(p_param), p_value); } } -float PinJoint3D::get_param(Param p_param) const { +real_t PinJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, 3, 0); return params[p_param]; } -RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void PinJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Vector3 pinpos = get_global_transform().origin; Vector3 local_a = body_a->get_global_transform().affine_inverse().xform(pinpos); Vector3 local_b; @@ -289,11 +296,10 @@ RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { local_b = pinpos; } - RID j = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_pin(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < 3; i++) { - PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PinJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer3D::PinJointParam(i), params[i]); } - return j; } PinJoint3D::PinJoint3D() { @@ -306,19 +312,19 @@ PinJoint3D::PinJoint3D() { /////////////////////////////////// -void HingeJoint3D::_set_upper_limit(float p_limit) { +void HingeJoint3D::_set_upper_limit(real_t p_limit) { set_param(PARAM_LIMIT_UPPER, Math::deg2rad(p_limit)); } -float HingeJoint3D::_get_upper_limit() const { +real_t HingeJoint3D::_get_upper_limit() const { return Math::rad2deg(get_param(PARAM_LIMIT_UPPER)); } -void HingeJoint3D::_set_lower_limit(float p_limit) { +void HingeJoint3D::_set_lower_limit(real_t p_limit) { set_param(PARAM_LIMIT_LOWER, Math::deg2rad(p_limit)); } -float HingeJoint3D::_get_lower_limit() const { +real_t HingeJoint3D::_get_lower_limit() const { return Math::rad2deg(get_param(PARAM_LIMIT_LOWER)); } @@ -363,17 +369,17 @@ void HingeJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_MAX); } -void HingeJoint3D::set_param(Param p_param, float p_value) { +void HingeJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value); } update_gizmo(); } -float HingeJoint3D::get_param(Param p_param) const { +real_t HingeJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params[p_param]; } @@ -381,7 +387,7 @@ float HingeJoint3D::get_param(Param p_param) const { void HingeJoint3D::set_flag(Flag p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags[p_flag] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value); } @@ -393,7 +399,7 @@ bool HingeJoint3D::get_flag(Flag p_flag) const { return flags[p_flag]; } -RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); Transform ainv = body_a->get_global_transform().affine_inverse(); @@ -408,15 +414,14 @@ RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_hinge(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HingeJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->hinge_joint_set_param(p_joint, PhysicsServer3D::HingeJointParam(i), params[i]); } for (int i = 0; i < FLAG_MAX; i++) { set_flag(Flag(i), flags[i]); - PhysicsServer3D::get_singleton()->hinge_joint_set_flag(j, PhysicsServer3D::HingeJointFlag(i), flags[i]); + PhysicsServer3D::get_singleton()->hinge_joint_set_flag(p_joint, PhysicsServer3D::HingeJointFlag(i), flags[i]); } - return j; } HingeJoint3D::HingeJoint3D() { @@ -437,19 +442,19 @@ HingeJoint3D::HingeJoint3D() { ////////////////////////////////// -void SliderJoint3D::_set_upper_limit_angular(float p_limit_angular) { +void SliderJoint3D::_set_upper_limit_angular(real_t p_limit_angular) { set_param(PARAM_ANGULAR_LIMIT_UPPER, Math::deg2rad(p_limit_angular)); } -float SliderJoint3D::_get_upper_limit_angular() const { +real_t SliderJoint3D::_get_upper_limit_angular() const { return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_UPPER)); } -void SliderJoint3D::_set_lower_limit_angular(float p_limit_angular) { +void SliderJoint3D::_set_lower_limit_angular(real_t p_limit_angular) { set_param(PARAM_ANGULAR_LIMIT_LOWER, Math::deg2rad(p_limit_angular)); } -float SliderJoint3D::_get_lower_limit_angular() const { +real_t SliderJoint3D::_get_lower_limit_angular() const { return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_LOWER)); } @@ -514,21 +519,21 @@ void SliderJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_MAX); } -void SliderJoint3D::set_param(Param p_param, float p_value) { +void SliderJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value); } update_gizmo(); } -float SliderJoint3D::get_param(Param p_param) const { +real_t SliderJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params[p_param]; } -RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); Transform ainv = body_a->get_global_transform().affine_inverse(); @@ -543,12 +548,10 @@ RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_slider(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SliderJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->slider_joint_set_param(p_joint, PhysicsServer3D::SliderJointParam(i), params[i]); } - - return j; } SliderJoint3D::SliderJoint3D() { @@ -579,19 +582,19 @@ SliderJoint3D::SliderJoint3D() { ////////////////////////////////// -void ConeTwistJoint3D::_set_swing_span(float p_limit_angular) { +void ConeTwistJoint3D::_set_swing_span(real_t p_limit_angular) { set_param(PARAM_SWING_SPAN, Math::deg2rad(p_limit_angular)); } -float ConeTwistJoint3D::_get_swing_span() const { +real_t ConeTwistJoint3D::_get_swing_span() const { return Math::rad2deg(get_param(PARAM_SWING_SPAN)); } -void ConeTwistJoint3D::_set_twist_span(float p_limit_angular) { +void ConeTwistJoint3D::_set_twist_span(real_t p_limit_angular) { set_param(PARAM_TWIST_SPAN, Math::deg2rad(p_limit_angular)); } -float ConeTwistJoint3D::_get_twist_span() const { +real_t ConeTwistJoint3D::_get_twist_span() const { return Math::rad2deg(get_param(PARAM_TWIST_SPAN)); } @@ -620,22 +623,22 @@ void ConeTwistJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_MAX); } -void ConeTwistJoint3D::set_param(Param p_param, float p_value) { +void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value); } update_gizmo(); } -float ConeTwistJoint3D::get_param(Param p_param) const { +real_t ConeTwistJoint3D::get_param(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params[p_param]; } -RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); @@ -653,12 +656,10 @@ RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *bod local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_cone_twist(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::ConeTwistJointParam(i), params[i]); + PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(p_joint, PhysicsServer3D::ConeTwistJointParam(i), params[i]); } - - return j; } ConeTwistJoint3D::ConeTwistJoint3D() { @@ -671,51 +672,51 @@ ConeTwistJoint3D::ConeTwistJoint3D() { ///////////////////////////////////////////////////////////////////// -void Generic6DOFJoint3D::_set_angular_hi_limit_x(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_hi_limit_x(real_t p_limit_angular) { set_param_x(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_hi_limit_x() const { +real_t Generic6DOFJoint3D::_get_angular_hi_limit_x() const { return Math::rad2deg(get_param_x(PARAM_ANGULAR_UPPER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_lo_limit_x(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_lo_limit_x(real_t p_limit_angular) { set_param_x(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_lo_limit_x() const { +real_t Generic6DOFJoint3D::_get_angular_lo_limit_x() const { return Math::rad2deg(get_param_x(PARAM_ANGULAR_LOWER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_hi_limit_y(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_hi_limit_y(real_t p_limit_angular) { set_param_y(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_hi_limit_y() const { +real_t Generic6DOFJoint3D::_get_angular_hi_limit_y() const { return Math::rad2deg(get_param_y(PARAM_ANGULAR_UPPER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_lo_limit_y(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_lo_limit_y(real_t p_limit_angular) { set_param_y(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_lo_limit_y() const { +real_t Generic6DOFJoint3D::_get_angular_lo_limit_y() const { return Math::rad2deg(get_param_y(PARAM_ANGULAR_LOWER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_hi_limit_z(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_hi_limit_z(real_t p_limit_angular) { set_param_z(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_hi_limit_z() const { +real_t Generic6DOFJoint3D::_get_angular_hi_limit_z() const { return Math::rad2deg(get_param_z(PARAM_ANGULAR_UPPER_LIMIT)); } -void Generic6DOFJoint3D::_set_angular_lo_limit_z(float p_limit_angular) { +void Generic6DOFJoint3D::_set_angular_lo_limit_z(real_t p_limit_angular) { set_param_z(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular)); } -float Generic6DOFJoint3D::_get_angular_lo_limit_z() const { +real_t Generic6DOFJoint3D::_get_angular_lo_limit_z() const { return Math::rad2deg(get_param_z(PARAM_ANGULAR_LOWER_LIMIT)); } @@ -877,45 +878,45 @@ void Generic6DOFJoint3D::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_MAX); } -void Generic6DOFJoint3D::set_param_x(Param p_param, float p_value) { +void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_x[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } update_gizmo(); } -float Generic6DOFJoint3D::get_param_x(Param p_param) const { +real_t Generic6DOFJoint3D::get_param_x(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_x[p_param]; } -void Generic6DOFJoint3D::set_param_y(Param p_param, float p_value) { +void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_y[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } update_gizmo(); } -float Generic6DOFJoint3D::get_param_y(Param p_param) const { +real_t Generic6DOFJoint3D::get_param_y(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_y[p_param]; } -void Generic6DOFJoint3D::set_param_z(Param p_param, float p_value) { +void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_z[p_param] = p_value; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value); } update_gizmo(); } -float Generic6DOFJoint3D::get_param_z(Param p_param) const { +real_t Generic6DOFJoint3D::get_param_z(Param p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_z[p_param]; } @@ -923,7 +924,7 @@ float Generic6DOFJoint3D::get_param_z(Param p_param) const { void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags_x[p_flag] = p_enabled; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } update_gizmo(); @@ -937,7 +938,7 @@ bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const { void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags_y[p_flag] = p_enabled; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } update_gizmo(); @@ -951,7 +952,7 @@ bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const { void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); flags_z[p_flag] = p_enabled; - if (get_joint().is_valid()) { + if (is_configured()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled); } update_gizmo(); @@ -962,7 +963,7 @@ bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const { return flags_z[p_flag]; } -RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) { +void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { Transform gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); @@ -980,19 +981,17 @@ RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *b local_b.orthonormalize(); - RID j = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); + PhysicsServer3D::get_singleton()->joint_make_generic_6dof(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b); for (int i = 0; i < PARAM_MAX; i++) { - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]); } for (int i = 0; i < FLAG_MAX; i++) { - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]); - PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]); + PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]); } - - return j; } Generic6DOFJoint3D::Generic6DOFJoint3D() { diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h index 9702076318..8d0a16e432 100644 --- a/scene/3d/physics_joint_3d.h +++ b/scene/3d/physics_joint_3d.h @@ -44,9 +44,10 @@ class Joint3D : public Node3D { NodePath a; NodePath b; - int solver_priority; - bool exclude_from_collision; + int solver_priority = 1; + bool exclude_from_collision = true; String warning; + bool configured = false; protected: void _disconnect_signals(); @@ -55,10 +56,12 @@ protected: void _notification(int p_what); - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0; static void _bind_methods(); + _FORCE_INLINE_ bool is_configured() const { return configured; } + public: virtual String get_configuration_warning() const override; @@ -76,6 +79,7 @@ public: RID get_joint() const { return joint; } Joint3D(); + ~Joint3D(); }; /////////////////////////////////////////// @@ -91,13 +95,13 @@ public: }; protected: - float params[3]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + real_t params[3]; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; PinJoint3D(); }; @@ -127,20 +131,20 @@ public: }; protected: - float params[PARAM_MAX]; + real_t params[PARAM_MAX]; bool flags[FLAG_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); - void _set_upper_limit(float p_limit); - float _get_upper_limit() const; + void _set_upper_limit(real_t p_limit); + real_t _get_upper_limit() const; - void _set_lower_limit(float p_limit); - float _get_lower_limit() const; + void _set_lower_limit(real_t p_limit); + real_t _get_lower_limit() const; public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; void set_flag(Flag p_flag, bool p_value); bool get_flag(Flag p_flag) const; @@ -184,19 +188,19 @@ public: }; protected: - void _set_upper_limit_angular(float p_limit_angular); - float _get_upper_limit_angular() const; + void _set_upper_limit_angular(real_t p_limit_angular); + real_t _get_upper_limit_angular() const; - void _set_lower_limit_angular(float p_limit_angular); - float _get_lower_limit_angular() const; + void _set_lower_limit_angular(real_t p_limit_angular); + real_t _get_lower_limit_angular() const; - float params[PARAM_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + real_t params[PARAM_MAX]; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; SliderJoint3D(); }; @@ -217,19 +221,19 @@ public: }; protected: - void _set_swing_span(float p_limit_angular); - float _get_swing_span() const; + void _set_swing_span(real_t p_limit_angular); + real_t _get_swing_span() const; - void _set_twist_span(float p_limit_angular); - float _get_twist_span() const; + void _set_twist_span(real_t p_limit_angular); + real_t _get_twist_span() const; - float params[PARAM_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + real_t params[PARAM_MAX]; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param(Param p_param, float p_value); - float get_param(Param p_param) const; + void set_param(Param p_param, real_t p_value); + real_t get_param(Param p_param) const; ConeTwistJoint3D(); }; @@ -277,43 +281,43 @@ public: }; protected: - void _set_angular_hi_limit_x(float p_limit_angular); - float _get_angular_hi_limit_x() const; + void _set_angular_hi_limit_x(real_t p_limit_angular); + real_t _get_angular_hi_limit_x() const; - void _set_angular_hi_limit_y(float p_limit_angular); - float _get_angular_hi_limit_y() const; + void _set_angular_hi_limit_y(real_t p_limit_angular); + real_t _get_angular_hi_limit_y() const; - void _set_angular_hi_limit_z(float p_limit_angular); - float _get_angular_hi_limit_z() const; + void _set_angular_hi_limit_z(real_t p_limit_angular); + real_t _get_angular_hi_limit_z() const; - void _set_angular_lo_limit_x(float p_limit_angular); - float _get_angular_lo_limit_x() const; + void _set_angular_lo_limit_x(real_t p_limit_angular); + real_t _get_angular_lo_limit_x() const; - void _set_angular_lo_limit_y(float p_limit_angular); - float _get_angular_lo_limit_y() const; + void _set_angular_lo_limit_y(real_t p_limit_angular); + real_t _get_angular_lo_limit_y() const; - void _set_angular_lo_limit_z(float p_limit_angular); - float _get_angular_lo_limit_z() const; + void _set_angular_lo_limit_z(real_t p_limit_angular); + real_t _get_angular_lo_limit_z() const; - float params_x[PARAM_MAX]; + real_t params_x[PARAM_MAX]; bool flags_x[FLAG_MAX]; - float params_y[PARAM_MAX]; + real_t params_y[PARAM_MAX]; bool flags_y[FLAG_MAX]; - float params_z[PARAM_MAX]; + real_t params_z[PARAM_MAX]; bool flags_z[FLAG_MAX]; - virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; + virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override; static void _bind_methods(); public: - void set_param_x(Param p_param, float p_value); - float get_param_x(Param p_param) const; + void set_param_x(Param p_param, real_t p_value); + real_t get_param_x(Param p_param) const; - void set_param_y(Param p_param, float p_value); - float get_param_y(Param p_param) const; + void set_param_y(Param p_param, real_t p_value); + real_t get_param_y(Param p_param) const; - void set_param_z(Param p_param, float p_value); - float get_param_z(Param p_param) const; + void set_param_z(Param p_param, real_t p_value); + real_t get_param_z(Param p_param) const; void set_flag_x(Flag p_flag, bool p_enabled); bool get_flag_x(Flag p_flag) const; diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 0b7c15a023..bfe79f15f5 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -392,13 +392,4 @@ void RayCast3D::_clear_debug_shape() { } RayCast3D::RayCast3D() { - enabled = true; - collided = false; - against_shape = 0; - collision_mask = 1; - target_position = Vector3(0, -1, 0); - debug_shape = nullptr; - exclude_parent_body = true; - collide_with_areas = false; - collide_with_bodies = true; } diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h index 4109853280..ae92189527 100644 --- a/scene/3d/ray_cast_3d.h +++ b/scene/3d/ray_cast_3d.h @@ -36,28 +36,28 @@ class RayCast3D : public Node3D { GDCLASS(RayCast3D, Node3D); - bool enabled; - bool collided; + bool enabled = true; + bool collided = false; ObjectID against; - int against_shape; + int against_shape = 0; Vector3 collision_point; Vector3 collision_normal; - Vector3 target_position; + Vector3 target_position = Vector3(0, -1, 0); Set<RID> exclude; - uint32_t collision_mask; - bool exclude_parent_body; + uint32_t collision_mask = 1; + bool exclude_parent_body = true; - Node *debug_shape; + Node *debug_shape = nullptr; Ref<Material> debug_material; void _create_debug_shape(); void _update_debug_shape(); void _clear_debug_shape(); - bool collide_with_areas; - bool collide_with_bodies; + bool collide_with_areas = false; + bool collide_with_bodies = true; protected: void _notification(int p_what); diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 63fa0c06c3..ad24f39bce 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -42,7 +42,7 @@ float ReflectionProbe::get_intensity() const { void ReflectionProbe::set_ambient_mode(AmbientMode p_mode) { ambient_mode = p_mode; RS::get_singleton()->reflection_probe_set_ambient_mode(probe, RS::ReflectionProbeAmbientMode(p_mode)); - _change_notify(); + notify_property_list_changed(); } ReflectionProbe::AmbientMode ReflectionProbe::get_ambient_mode() const { @@ -95,13 +95,12 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) { if (extents[i] - 0.01 < ABS(origin_offset[i])) { origin_offset[i] = SGN(origin_offset[i]) * (extents[i] - 0.01); - _change_notify("origin_offset"); } } RS::get_singleton()->reflection_probe_set_extents(probe, extents); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); - _change_notify("extents"); + update_gizmo(); } @@ -120,7 +119,6 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) { RS::get_singleton()->reflection_probe_set_extents(probe, extents); RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset); - _change_notify("origin_offset"); update_gizmo(); } @@ -257,20 +255,6 @@ void ReflectionProbe::_bind_methods() { } ReflectionProbe::ReflectionProbe() { - intensity = 1.0; - ambient_mode = AMBIENT_ENVIRONMENT; - ambient_color = Color(0, 0, 0); - ambient_color_energy = 1.0; - max_distance = 0; - extents = Vector3(1, 1, 1); - origin_offset = Vector3(0, 0, 0); - box_projection = false; - interior = false; - enable_shadows = false; - cull_mask = (1 << 20) - 1; - update_mode = UPDATE_ONCE; - lod_threshold = 1.0; - probe = RenderingServer::get_singleton()->reflection_probe_create(); RS::get_singleton()->instance_set_base(get_instance(), probe); set_disable_scale(true); diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index a43d4e2422..15c2da3ae0 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -53,20 +53,20 @@ public: private: RID probe; - float intensity; - float max_distance; - Vector3 extents; - Vector3 origin_offset; - bool box_projection; - bool enable_shadows; - bool interior; - AmbientMode ambient_mode; - Color ambient_color; - float ambient_color_energy; - float lod_threshold; - - uint32_t cull_mask; - UpdateMode update_mode; + float intensity = 1.0; + float max_distance = 0.0; + Vector3 extents = Vector3(1, 1, 1); + Vector3 origin_offset = Vector3(0, 0, 0); + bool box_projection = false; + bool enable_shadows = false; + bool interior = false; + AmbientMode ambient_mode = AMBIENT_ENVIRONMENT; + Color ambient_color = Color(0, 0, 0); + float ambient_color_energy = 1.0; + float lod_threshold = 1.0; + + uint32_t cull_mask = (1 << 20) - 1; + UpdateMode update_mode = UPDATE_ONCE; protected: static void _bind_methods(); diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp index 4afbb80779..83ac813c53 100644 --- a/scene/3d/remote_transform_3d.cpp +++ b/scene/3d/remote_transform_3d.cpp @@ -217,10 +217,5 @@ void RemoteTransform3D::_bind_methods() { } RemoteTransform3D::RemoteTransform3D() { - use_global_coordinates = true; - update_remote_position = true; - update_remote_rotation = true; - update_remote_scale = true; - set_notify_transform(true); } diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h index 3b30c835be..21005d92d1 100644 --- a/scene/3d/remote_transform_3d.h +++ b/scene/3d/remote_transform_3d.h @@ -40,10 +40,10 @@ class RemoteTransform3D : public Node3D { ObjectID cache; - bool use_global_coordinates; - bool update_remote_position; - bool update_remote_rotation; - bool update_remote_scale; + bool use_global_coordinates = true; + bool update_remote_position = true; + bool update_remote_rotation = true; + bool update_remote_scale = true; void _update_remote(); void _update_cache(); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 5e09a15b80..be62fe801f 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -304,7 +304,7 @@ void Skeleton3D::_notification(int p_what) { uint32_t bind_count = skin->get_bind_count(); if (E->get()->bind_count != bind_count) { - RS::get_singleton()->skeleton_allocate(skeleton, bind_count); + RS::get_singleton()->skeleton_allocate_data(skeleton, bind_count); E->get()->bind_count = bind_count; E->get()->skin_bone_indices.resize(bind_count); E->get()->skin_bone_indices_ptrs = E->get()->skin_bone_indices.ptrw(); @@ -927,10 +927,6 @@ void Skeleton3D::_bind_methods() { } Skeleton3D::Skeleton3D() { - animate_physical_bones = true; - dirty = false; - version = 1; - process_order_dirty = true; } Skeleton3D::~Skeleton3D() { diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 73417dce21..9772bfcc95 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -74,57 +74,44 @@ private: struct Bone { String name; - bool enabled; - int parent; - int sort_index; //used for re-sorting process order + bool enabled = true; + int parent = -1; + int sort_index = 0; //used for re-sorting process order - bool disable_rest; + bool disable_rest = false; Transform rest; Transform pose; Transform pose_global; - bool custom_pose_enable; + bool custom_pose_enable = false; Transform custom_pose; - float global_pose_override_amount; - bool global_pose_override_reset; + float global_pose_override_amount = 0.0; + bool global_pose_override_reset = false; Transform global_pose_override; #ifndef _3D_DISABLED - PhysicalBone3D *physical_bone; - PhysicalBone3D *cache_parent_physical_bone; + PhysicalBone3D *physical_bone = nullptr; + PhysicalBone3D *cache_parent_physical_bone = nullptr; #endif // _3D_DISABLED List<ObjectID> nodes_bound; - - Bone() { - parent = -1; - enabled = true; - disable_rest = false; - custom_pose_enable = false; - global_pose_override_amount = 0; - global_pose_override_reset = false; -#ifndef _3D_DISABLED - physical_bone = nullptr; - cache_parent_physical_bone = nullptr; -#endif // _3D_DISABLED - } }; Set<SkinReference *> skin_bindings; void _skin_changed(); - bool animate_physical_bones; + bool animate_physical_bones = true; Vector<Bone> bones; Vector<int> process_order; - bool process_order_dirty; + bool process_order_dirty = true; void _make_dirty(); - bool dirty; + bool dirty = false; - uint64_t version; + uint64_t version = 1; // bind helpers Array _get_bound_child_nodes_to_bone(int p_bone) const { diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 557647aa62..eefecf68bb 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -54,15 +54,13 @@ class FabrikInverseKinematic { BoneId bone = -1; PhysicalBone3D *pb = nullptr; - real_t length = 0; + real_t length = 0.0; /// Positions relative to root bone Transform initial_transform; Vector3 current_pos; // Direction from this bone to child Vector3 current_ori; - ChainItem() {} - ChainItem *find_child(const BoneId p_bone_id); ChainItem *add_child(const BoneId p_bone_id); }; @@ -80,7 +78,7 @@ class FabrikInverseKinematic { struct Chain { ChainItem chain_root; - ChainItem *middle_chain_item; + ChainItem *middle_chain_item = nullptr; Vector<ChainTip> tips; Vector3 magnet_position; }; @@ -130,7 +128,7 @@ class SkeletonIK3D : public Node { StringName root_bone; StringName tip_bone; - real_t interpolation = 1; + real_t interpolation = 1.0; Transform target; NodePath target_node_path_override; bool override_tip_basis = true; diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 785465f28e..2d8f22ab37 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -245,13 +245,11 @@ bool SoftBody3D::_get_property_pinned_points(int p_item, const String &p_what, V return true; } -void SoftBody3D::_changed_callback(Object *p_changed, const char *p_prop) { +void SoftBody3D::_softbody_changed() { prepare_physics_server(); _reset_points_offsets(); #ifdef TOOLS_ENABLED - if (p_changed == this) { - update_configuration_warning(); - } + update_configuration_warning(); #endif } @@ -259,7 +257,9 @@ void SoftBody3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { if (Engine::get_singleton()->is_editor_hint()) { - add_change_receptor(this); + // I have no idea what this is supposed to do, it's really weird + // leaving for upcoming PK work on physics + //add_change_receptor(this); } RID space = get_world_3d()->get_space(); @@ -337,8 +337,8 @@ void SoftBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness); ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness); - ClassDB::bind_method(D_METHOD("set_areaAngular_stiffness", "areaAngular_stiffness"), &SoftBody3D::set_areaAngular_stiffness); - ClassDB::bind_method(D_METHOD("get_areaAngular_stiffness"), &SoftBody3D::get_areaAngular_stiffness); + ClassDB::bind_method(D_METHOD("set_angular_stiffness", "angular_stiffness"), &SoftBody3D::set_angular_stiffness); + ClassDB::bind_method(D_METHOD("get_angular_stiffness"), &SoftBody3D::get_angular_stiffness); ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness); ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness); @@ -366,7 +366,7 @@ void SoftBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_angular_stiffness", "get_angular_stiffness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); @@ -612,12 +612,12 @@ real_t SoftBody3D::get_linear_stiffness() { return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid); } -void SoftBody3D::set_areaAngular_stiffness(real_t p_areaAngular_stiffness) { - PhysicsServer3D::get_singleton()->soft_body_set_areaAngular_stiffness(physics_rid, p_areaAngular_stiffness); +void SoftBody3D::set_angular_stiffness(real_t p_angular_stiffness) { + PhysicsServer3D::get_singleton()->soft_body_set_angular_stiffness(physics_rid, p_angular_stiffness); } -real_t SoftBody3D::get_areaAngular_stiffness() { - return PhysicsServer3D::get_singleton()->soft_body_get_areaAngular_stiffness(physics_rid); +real_t SoftBody3D::get_angular_stiffness() { + return PhysicsServer3D::get_singleton()->soft_body_get_angular_stiffness(physics_rid); } void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) { diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h index d3c5dc022f..6e24a530bd 100644 --- a/scene/3d/soft_body_3d.h +++ b/scene/3d/soft_body_3d.h @@ -39,13 +39,13 @@ class SoftBodyRenderingServerHandler { friend class SoftBody3D; RID mesh; - int surface; + int surface = 0; Vector<uint8_t> buffer; - uint32_t stride; - uint32_t offset_vertices; - uint32_t offset_normal; + uint32_t stride = 0; + uint32_t offset_vertices = 0; + uint32_t offset_normal = 0; - uint8_t *write_buffer; + uint8_t *write_buffer = nullptr; private: SoftBodyRenderingServerHandler(); @@ -91,13 +91,15 @@ private: bool pinned_points_cache_dirty = true; Ref<ArrayMesh> debug_mesh_cache; - class MeshInstance3D *debug_mesh; + class MeshInstance3D *debug_mesh = nullptr; - bool capture_input_on_drag; + bool capture_input_on_drag = false; bool ray_pickable = true; void _update_pickable(); + void _softbody_changed(); + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -107,8 +109,6 @@ protected: bool _set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value); bool _get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const; - virtual void _changed_callback(Object *p_changed, const char *p_prop) override; - void _notification(int p_what); static void _bind_methods(); @@ -149,8 +149,8 @@ public: void set_linear_stiffness(real_t p_linear_stiffness); real_t get_linear_stiffness(); - void set_areaAngular_stiffness(real_t p_areaAngular_stiffness); - real_t get_areaAngular_stiffness(); + void set_angular_stiffness(real_t p_angular_stiffness); + real_t get_angular_stiffness(); void set_volume_stiffness(real_t p_volume_stiffness); real_t get_volume_stiffness(); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 6812282844..9518b47696 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -78,11 +78,11 @@ void SpringArm3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); } -float SpringArm3D::get_length() const { +real_t SpringArm3D::get_length() const { return spring_length; } -void SpringArm3D::set_length(float p_length) { +void SpringArm3D::set_length(real_t p_length) { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) { update_gizmo(); } @@ -106,11 +106,11 @@ uint32_t SpringArm3D::get_mask() { return mask; } -float SpringArm3D::get_margin() { +real_t SpringArm3D::get_margin() { return margin; } -void SpringArm3D::set_margin(float p_margin) { +void SpringArm3D::set_margin(real_t p_margin) { margin = p_margin; } @@ -126,7 +126,7 @@ void SpringArm3D::clear_excluded_objects() { excluded_objects.clear(); } -float SpringArm3D::get_hit_length() { +real_t SpringArm3D::get_hit_length() { return current_spring_length; } @@ -143,7 +143,7 @@ void SpringArm3D::process_spring() { PhysicsDirectSpaceState3D::RayResult r; bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask); if (intersected) { - float dist = get_global_transform().origin.distance_to(r.position); + real_t dist = get_global_transform().origin.distance_to(r.position); dist -= margin; motion_delta = dist / (spring_length); } diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h index 4c2d2a54ff..63505ab9d3 100644 --- a/scene/3d/spring_arm_3d.h +++ b/scene/3d/spring_arm_3d.h @@ -38,19 +38,19 @@ class SpringArm3D : public Node3D { Ref<Shape3D> shape; Set<RID> excluded_objects; - float spring_length = 1; - float current_spring_length = 0; + real_t spring_length = 1.0; + real_t current_spring_length = 0.0; bool keep_child_basis = false; uint32_t mask = 1; - float margin = 0.01; + real_t margin = 0.01; protected: void _notification(int p_what); static void _bind_methods(); public: - void set_length(float p_length); - float get_length() const; + void set_length(real_t p_length); + real_t get_length() const; void set_shape(Ref<Shape3D> p_shape); Ref<Shape3D> get_shape() const; void set_mask(uint32_t p_mask); @@ -58,9 +58,9 @@ public: void add_excluded_object(RID p_rid); bool remove_excluded_object(RID p_rid); void clear_excluded_objects(); - float get_hit_length(); - void set_margin(float p_margin); - float get_margin(); + real_t get_hit_length(); + void set_margin(real_t p_margin); + real_t get_margin(); SpringArm3D() {} diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 3e49750366..c26224d0e3 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -339,24 +339,10 @@ void SpriteBase3D::_bind_methods() { } SpriteBase3D::SpriteBase3D() { - color_dirty = true; - centered = true; - hflip = false; - vflip = false; - parent_sprite = nullptr; - pI = nullptr; - for (int i = 0; i < FLAG_MAX; i++) { flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED; } - alpha_cut = ALPHA_CUT_DISABLED; - billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; - axis = Vector3::AXIS_Z; - pixel_size = 0.01; - modulate = Color(1, 1, 1, 1); - pending_update = false; - opacity = 1.0; immediate = RenderingServer::get_singleton()->immediate_create(); set_base(immediate); } @@ -557,8 +543,6 @@ void Sprite3D::set_frame(int p_frame) { _queue_update(); - _change_notify("frame"); - _change_notify("frame_coords"); emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -581,7 +565,7 @@ void Sprite3D::set_vframes(int p_amount) { ERR_FAIL_COND(p_amount < 1); vframes = p_amount; _queue_update(); - _change_notify(); + notify_property_list_changed(); } int Sprite3D::get_vframes() const { @@ -592,7 +576,7 @@ void Sprite3D::set_hframes(int p_amount) { ERR_FAIL_COND(p_amount < 1); hframes = p_amount; _queue_update(); - _change_notify(); + notify_property_list_changed(); } int Sprite3D::get_hframes() const { @@ -909,7 +893,6 @@ void AnimatedSprite3D::_notification(int p_what) { } _queue_update(); - _change_notify("frame"); } float to_process = MIN(timeout, remaining); @@ -935,7 +918,7 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { set_frame(frame); } - _change_notify(); + notify_property_list_changed(); _reset_timeout(); _queue_update(); update_configuration_warning(); @@ -968,7 +951,7 @@ void AnimatedSprite3D::set_frame(int p_frame) { frame = p_frame; _reset_timeout(); _queue_update(); - _change_notify("frame"); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } @@ -1004,8 +987,6 @@ Rect2 AnimatedSprite3D::get_item_rect() const { void AnimatedSprite3D::_res_changed() { set_frame(frame); - _change_notify("frame"); - _change_notify("animation"); _queue_update(); } @@ -1062,7 +1043,7 @@ void AnimatedSprite3D::set_animation(const StringName &p_animation) { animation = p_animation; _reset_timeout(); set_frame(0); - _change_notify(); + notify_property_list_changed(); _queue_update(); } @@ -1109,8 +1090,4 @@ void AnimatedSprite3D::_bind_methods() { } AnimatedSprite3D::AnimatedSprite3D() { - frame = 0; - playing = false; - animation = "default"; - timeout = 0; } diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 3e38d4581e..a9ce2d8eee 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -55,32 +55,32 @@ public: }; private: - bool color_dirty; + bool color_dirty = true; Color color_accum; - SpriteBase3D *parent_sprite; + SpriteBase3D *parent_sprite = nullptr; List<SpriteBase3D *> children; - List<SpriteBase3D *>::Element *pI; + List<SpriteBase3D *>::Element *pI = nullptr; - bool centered; + bool centered = true; Point2 offset; - bool hflip; - bool vflip; + bool hflip = false; + bool vflip = false; - Color modulate; - float opacity; + Color modulate = Color(1, 1, 1, 1); + float opacity = 1.0; - Vector3::Axis axis; - float pixel_size; + Vector3::Axis axis = Vector3::AXIS_Z; + float pixel_size = 0.01; AABB aabb; RID immediate; bool flags[FLAG_MAX]; - AlphaCutMode alpha_cut; - StandardMaterial3D::BillboardMode billboard_mode; - bool pending_update; + AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED; + StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; + bool pending_update = false; void _im_update(); void _propagate_color_changed(); @@ -195,16 +195,16 @@ class AnimatedSprite3D : public SpriteBase3D { GDCLASS(AnimatedSprite3D, SpriteBase3D); Ref<SpriteFrames> frames; - bool playing; - StringName animation; - int frame; + bool playing = false; + StringName animation = "default"; + int frame = 0; - bool centered; + bool centered = true; - float timeout; + float timeout = 0.0; - bool hflip; - bool vflip; + bool hflip = 1; + bool vflip = 1; Color modulate; diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 120bbbae43..0d25e2f21f 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -147,77 +147,77 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) { } } -void VehicleWheel3D::set_radius(float p_radius) { +void VehicleWheel3D::set_radius(real_t p_radius) { m_wheelRadius = p_radius; update_gizmo(); } -float VehicleWheel3D::get_radius() const { +real_t VehicleWheel3D::get_radius() const { return m_wheelRadius; } -void VehicleWheel3D::set_suspension_rest_length(float p_length) { +void VehicleWheel3D::set_suspension_rest_length(real_t p_length) { m_suspensionRestLength = p_length; update_gizmo(); } -float VehicleWheel3D::get_suspension_rest_length() const { +real_t VehicleWheel3D::get_suspension_rest_length() const { return m_suspensionRestLength; } -void VehicleWheel3D::set_suspension_travel(float p_length) { +void VehicleWheel3D::set_suspension_travel(real_t p_length) { m_maxSuspensionTravelCm = p_length / 0.01; } -float VehicleWheel3D::get_suspension_travel() const { +real_t VehicleWheel3D::get_suspension_travel() const { return m_maxSuspensionTravelCm * 0.01; } -void VehicleWheel3D::set_suspension_stiffness(float p_value) { +void VehicleWheel3D::set_suspension_stiffness(real_t p_value) { m_suspensionStiffness = p_value; } -float VehicleWheel3D::get_suspension_stiffness() const { +real_t VehicleWheel3D::get_suspension_stiffness() const { return m_suspensionStiffness; } -void VehicleWheel3D::set_suspension_max_force(float p_value) { +void VehicleWheel3D::set_suspension_max_force(real_t p_value) { m_maxSuspensionForce = p_value; } -float VehicleWheel3D::get_suspension_max_force() const { +real_t VehicleWheel3D::get_suspension_max_force() const { return m_maxSuspensionForce; } -void VehicleWheel3D::set_damping_compression(float p_value) { +void VehicleWheel3D::set_damping_compression(real_t p_value) { m_wheelsDampingCompression = p_value; } -float VehicleWheel3D::get_damping_compression() const { +real_t VehicleWheel3D::get_damping_compression() const { return m_wheelsDampingCompression; } -void VehicleWheel3D::set_damping_relaxation(float p_value) { +void VehicleWheel3D::set_damping_relaxation(real_t p_value) { m_wheelsDampingRelaxation = p_value; } -float VehicleWheel3D::get_damping_relaxation() const { +real_t VehicleWheel3D::get_damping_relaxation() const { return m_wheelsDampingRelaxation; } -void VehicleWheel3D::set_friction_slip(float p_value) { +void VehicleWheel3D::set_friction_slip(real_t p_value) { m_frictionSlip = p_value; } -float VehicleWheel3D::get_friction_slip() const { +real_t VehicleWheel3D::get_friction_slip() const { return m_frictionSlip; } -void VehicleWheel3D::set_roll_influence(float p_value) { +void VehicleWheel3D::set_roll_influence(real_t p_value) { m_rollInfluence = p_value; } -float VehicleWheel3D::get_roll_influence() const { +real_t VehicleWheel3D::get_roll_influence() const { return m_rollInfluence; } @@ -295,27 +295,27 @@ void VehicleWheel3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation"); } -void VehicleWheel3D::set_engine_force(float p_engine_force) { +void VehicleWheel3D::set_engine_force(real_t p_engine_force) { m_engineForce = p_engine_force; } -float VehicleWheel3D::get_engine_force() const { +real_t VehicleWheel3D::get_engine_force() const { return m_engineForce; } -void VehicleWheel3D::set_brake(float p_brake) { +void VehicleWheel3D::set_brake(real_t p_brake) { m_brake = p_brake; } -float VehicleWheel3D::get_brake() const { +real_t VehicleWheel3D::get_brake() const { return m_brake; } -void VehicleWheel3D::set_steering(float p_steering) { +void VehicleWheel3D::set_steering(real_t p_steering) { m_steering = p_steering; } -float VehicleWheel3D::get_steering() const { +real_t VehicleWheel3D::get_steering() const { return m_steering; } @@ -335,39 +335,15 @@ bool VehicleWheel3D::is_used_as_steering() const { return steers; } -float VehicleWheel3D::get_skidinfo() const { +real_t VehicleWheel3D::get_skidinfo() const { return m_skidInfo; } -float VehicleWheel3D::get_rpm() const { +real_t VehicleWheel3D::get_rpm() const { return m_rpm; } VehicleWheel3D::VehicleWheel3D() { - steers = false; - engine_traction = false; - m_steering = real_t(0.); - m_engineForce = real_t(0.); - m_rotation = real_t(0.); - m_deltaRotation = real_t(0.); - m_brake = real_t(0.); - m_rollInfluence = real_t(0.1); - - m_suspensionRestLength = 0.15; - m_wheelRadius = 0.5; //0.28; - m_suspensionStiffness = 5.88; - m_wheelsDampingCompression = 0.83; - m_wheelsDampingRelaxation = 0.88; - m_frictionSlip = 10.5; - m_bIsFrontWheel = false; - m_maxSuspensionTravelCm = 500; - m_maxSuspensionForce = 6000; - - m_suspensionRelativeVelocity = 0; - m_clippedInvContactDotSuspension = 1.0; - m_raycastInfo.m_isInContact = false; - - body = nullptr; } void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) { @@ -564,7 +540,7 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const Vector3 vel = vel1 - vel2; Basis b2trans; - float b2invmass = 0; + real_t b2invmass = 0; Vector3 b2lv; Vector3 b2av; Vector3 b2invinertia; //todo @@ -622,8 +598,8 @@ VehicleBody3D::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDir m_frictionPositionWorld(frictionPosWorld), m_frictionDirectionWorld(frictionDirectionWorld), m_maxImpulse(maxImpulse) { - float denom0 = 0; - float denom1 = 0; + real_t denom0 = 0; + real_t denom1 = 0; { Vector3 r0 = frictionPosWorld - s->get_transform().origin; @@ -831,7 +807,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) { state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); - float step = state->get_step(); + real_t step = state->get_step(); for (int i = 0; i < wheels.size(); i++) { _update_wheel(i, state); @@ -891,7 +867,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) { state = nullptr; } -void VehicleBody3D::set_engine_force(float p_engine_force) { +void VehicleBody3D::set_engine_force(real_t p_engine_force) { engine_force = p_engine_force; for (int i = 0; i < wheels.size(); i++) { VehicleWheel3D &wheelInfo = *wheels[i]; @@ -901,11 +877,11 @@ void VehicleBody3D::set_engine_force(float p_engine_force) { } } -float VehicleBody3D::get_engine_force() const { +real_t VehicleBody3D::get_engine_force() const { return engine_force; } -void VehicleBody3D::set_brake(float p_brake) { +void VehicleBody3D::set_brake(real_t p_brake) { brake = p_brake; for (int i = 0; i < wheels.size(); i++) { VehicleWheel3D &wheelInfo = *wheels[i]; @@ -913,11 +889,11 @@ void VehicleBody3D::set_brake(float p_brake) { } } -float VehicleBody3D::get_brake() const { +real_t VehicleBody3D::get_brake() const { return brake; } -void VehicleBody3D::set_steering(float p_steering) { +void VehicleBody3D::set_steering(real_t p_steering) { m_steeringValue = p_steering; for (int i = 0; i < wheels.size(); i++) { VehicleWheel3D &wheelInfo = *wheels[i]; @@ -927,7 +903,7 @@ void VehicleBody3D::set_steering(float p_steering) { } } -float VehicleBody3D::get_steering() const { +real_t VehicleBody3D::get_steering() const { return m_steeringValue; } @@ -948,16 +924,6 @@ void VehicleBody3D::_bind_methods() { } VehicleBody3D::VehicleBody3D() { - m_pitchControl = 0; - m_currentVehicleSpeedKmHour = real_t(0.); - m_steeringValue = real_t(0.); - - engine_force = 0; - brake = 0; - - state = nullptr; - ccd = false; - exclude.insert(get_rid()); //PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index ca7ea6574d..860fa7e3b7 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -42,52 +42,52 @@ class VehicleWheel3D : public Node3D { Transform m_worldTransform; Transform local_xform; - bool engine_traction; - bool steers; + bool engine_traction = false; + bool steers = false; Vector3 m_chassisConnectionPointCS; //const Vector3 m_wheelDirectionCS; //const Vector3 m_wheelAxleCS; // const or modified by steering - real_t m_suspensionRestLength; - real_t m_maxSuspensionTravelCm; - real_t m_wheelRadius; + real_t m_suspensionRestLength = 0.15; + real_t m_maxSuspensionTravelCm = 500.0; + real_t m_wheelRadius = 0.5; - real_t m_suspensionStiffness; - real_t m_wheelsDampingCompression; - real_t m_wheelsDampingRelaxation; - real_t m_frictionSlip; - real_t m_maxSuspensionForce; - bool m_bIsFrontWheel; + real_t m_suspensionStiffness = 5.88; + real_t m_wheelsDampingCompression = 0.83; + real_t m_wheelsDampingRelaxation = 0.88; + real_t m_frictionSlip = 10.5; + real_t m_maxSuspensionForce = 6000.0; + bool m_bIsFrontWheel = false; - VehicleBody3D *body; + VehicleBody3D *body = nullptr; //btVector3 m_wheelAxleCS; // const or modified by steering ? - real_t m_steering; - real_t m_rotation; - real_t m_deltaRotation; - real_t m_rpm; - real_t m_rollInfluence; - real_t m_engineForce; - real_t m_brake; + real_t m_steering = 0.0; + real_t m_rotation = 0.0; + real_t m_deltaRotation = 0.0; + real_t m_rpm = 0.0; + real_t m_rollInfluence = 0.1; + real_t m_engineForce = 0.0; + real_t m_brake = 0.0; - real_t m_clippedInvContactDotSuspension; - real_t m_suspensionRelativeVelocity; + real_t m_clippedInvContactDotSuspension = 1.0; + real_t m_suspensionRelativeVelocity = 0.0; //calculated by suspension - real_t m_wheelsSuspensionForce; - real_t m_skidInfo; + real_t m_wheelsSuspensionForce = 0.0; + real_t m_skidInfo = 0.0; struct RaycastInfo { //set by raycaster Vector3 m_contactNormalWS; //contactnormal Vector3 m_contactPointWS; //raycast hitpoint - real_t m_suspensionLength; + real_t m_suspensionLength = 0.0; Vector3 m_hardPointWS; //raycast starting point Vector3 m_wheelDirectionWS; //direction in worldspace Vector3 m_wheelAxleWS; // axle in worldspace - bool m_isInContact; - PhysicsBody3D *m_groundObject; //could be general void* ptr + bool m_isInContact = false; + PhysicsBody3D *m_groundObject = nullptr; //could be general void* ptr } m_raycastInfo; void _update(PhysicsDirectBodyState3D *s); @@ -97,29 +97,29 @@ protected: static void _bind_methods(); public: - void set_radius(float p_radius); - float get_radius() const; + void set_radius(real_t p_radius); + real_t get_radius() const; - void set_suspension_rest_length(float p_length); - float get_suspension_rest_length() const; + void set_suspension_rest_length(real_t p_length); + real_t get_suspension_rest_length() const; - void set_suspension_travel(float p_length); - float get_suspension_travel() const; + void set_suspension_travel(real_t p_length); + real_t get_suspension_travel() const; - void set_suspension_stiffness(float p_value); - float get_suspension_stiffness() const; + void set_suspension_stiffness(real_t p_value); + real_t get_suspension_stiffness() const; - void set_suspension_max_force(float p_value); - float get_suspension_max_force() const; + void set_suspension_max_force(real_t p_value); + real_t get_suspension_max_force() const; - void set_damping_compression(float p_value); - float get_damping_compression() const; + void set_damping_compression(real_t p_value); + real_t get_damping_compression() const; - void set_damping_relaxation(float p_value); - float get_damping_relaxation() const; + void set_damping_relaxation(real_t p_value); + real_t get_damping_relaxation() const; - void set_friction_slip(float p_value); - float get_friction_slip() const; + void set_friction_slip(real_t p_value); + real_t get_friction_slip() const; void set_use_as_traction(bool p_enable); bool is_used_as_traction() const; @@ -129,21 +129,21 @@ public: bool is_in_contact() const; - void set_roll_influence(float p_value); - float get_roll_influence() const; + void set_roll_influence(real_t p_value); + real_t get_roll_influence() const; - float get_skidinfo() const; + real_t get_skidinfo() const; - float get_rpm() const; + real_t get_rpm() const; - void set_engine_force(float p_engine_force); - float get_engine_force() const; + void set_engine_force(real_t p_engine_force); + real_t get_engine_force() const; - void set_brake(float p_brake); - float get_brake() const; + void set_brake(real_t p_brake); + real_t get_brake() const; - void set_steering(float p_steering); - float get_steering() const; + void set_steering(real_t p_steering); + real_t get_steering() const; String get_configuration_warning() const override; @@ -153,12 +153,12 @@ public: class VehicleBody3D : public RigidBody3D { GDCLASS(VehicleBody3D, RigidBody3D); - float engine_force; - float brake; + real_t engine_force = 0.0; + real_t brake = 0.0; - real_t m_pitchControl; - real_t m_steeringValue; - real_t m_currentVehicleSpeedKmHour; + real_t m_pitchControl = 0.0; + real_t m_steeringValue = 0.0; + real_t m_currentVehicleSpeedKmHour = 0.0; Set<RID> exclude; @@ -168,12 +168,12 @@ class VehicleBody3D : public RigidBody3D { Vector<real_t> m_sideImpulse; struct btVehicleWheelContactPoint { - PhysicsDirectBodyState3D *m_s; - PhysicsBody3D *m_body1; + PhysicsDirectBodyState3D *m_s = nullptr; + PhysicsBody3D *m_body1 = nullptr; Vector3 m_frictionPositionWorld; Vector3 m_frictionDirectionWorld; - real_t m_jacDiagABInv; - real_t m_maxImpulse; + real_t m_jacDiagABInv = 0.0; + real_t m_maxImpulse = 0.0; btVehicleWheelContactPoint(PhysicsDirectBodyState3D *s, PhysicsBody3D *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse); }; @@ -195,14 +195,14 @@ class VehicleBody3D : public RigidBody3D { void _direct_state_changed(Object *p_state) override; public: - void set_engine_force(float p_engine_force); - float get_engine_force() const; + void set_engine_force(real_t p_engine_force); + real_t get_engine_force() const; - void set_brake(float p_brake); - float get_brake() const; + void set_brake(real_t p_brake); + real_t get_brake() const; - void set_steering(float p_steering); - float get_steering() const; + void set_steering(real_t p_steering); + real_t get_steering() const; VehicleBody3D(); }; diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp index 35d00f3639..5b5cc06456 100644 --- a/scene/3d/velocity_tracker_3d.cpp +++ b/scene/3d/velocity_tracker_3d.cpp @@ -128,6 +128,4 @@ void VelocityTracker3D::_bind_methods() { VelocityTracker3D::VelocityTracker3D() { position_history.resize(4); // should be configurable - position_history_len = 0; - physics_step = false; } diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h index 3fc89cc7fb..e971f4755a 100644 --- a/scene/3d/velocity_tracker_3d.h +++ b/scene/3d/velocity_tracker_3d.h @@ -37,13 +37,13 @@ class VelocityTracker3D : public Reference { GDCLASS(VelocityTracker3D, Reference); struct PositionHistory { - uint64_t frame; + uint64_t frame = 0; Vector3 position; }; - bool physics_step; + bool physics_step = false; Vector<PositionHistory> position_history; - int position_history_len; + int position_history_len = 0; protected: static void _bind_methods(); diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp index 14c7659de4..471838b9d1 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -69,7 +69,6 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) { get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb)); } - _change_notify("aabb"); update_gizmo(); } @@ -112,7 +111,6 @@ void VisibilityNotifier3D::_bind_methods() { } VisibilityNotifier3D::VisibilityNotifier3D() { - aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); set_notify_transform(true); } @@ -252,6 +250,4 @@ VisibilityEnabler3D::VisibilityEnabler3D() { for (int i = 0; i < ENABLER_MAX; i++) { enabler[i] = true; } - - visible = false; } diff --git a/scene/3d/visibility_notifier_3d.h b/scene/3d/visibility_notifier_3d.h index d566b7e40b..9f7705067f 100644 --- a/scene/3d/visibility_notifier_3d.h +++ b/scene/3d/visibility_notifier_3d.h @@ -41,7 +41,7 @@ class VisibilityNotifier3D : public Node3D { Ref<World3D> world; Set<Camera3D *> cameras; - AABB aabb; + AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); protected: virtual void _screen_enter() {} @@ -76,7 +76,7 @@ protected: virtual void _screen_enter() override; virtual void _screen_exit() override; - bool visible; + bool visible = false; void _find_nodes(Node *p_node); diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 1d0a830383..394c67e873 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -43,7 +43,6 @@ void VisualInstance3D::_update_visibility() { return; } - _change_notify("visible"); RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree()); } @@ -135,7 +134,6 @@ RID VisualInstance3D::get_base() const { VisualInstance3D::VisualInstance3D() { instance = RenderingServer::get_singleton()->instance_create(); RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id()); - layers = 1; set_notify_transform(true); } @@ -371,7 +369,7 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode); ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode); - ClassDB::bind_method(D_METHOD("set_lod_bias", "p_bias"), &GeometryInstance3D::set_lod_bias); + ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias); ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias); ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &GeometryInstance3D::set_custom_aabb); @@ -412,17 +410,5 @@ void GeometryInstance3D::_bind_methods() { } GeometryInstance3D::GeometryInstance3D() { - lod_min_distance = 0; - lod_max_distance = 0; - lod_min_hysteresis = 0; - lod_max_hysteresis = 0; - - lod_bias = 1.0; - - gi_mode = GI_MODE_DISABLED; - lightmap_scale = LIGHTMAP_SCALE_1X; - - shadow_casting_setting = SHADOW_CASTING_SETTING_ON; - extra_cull_margin = 0; //RS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0); } diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index f370f29cb0..7fed8095ef 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -42,7 +42,7 @@ class VisualInstance3D : public Node3D { RID base; RID instance; - uint32_t layers; + uint32_t layers = 1; RID _get_visual_instance_rid() const; @@ -105,21 +105,21 @@ public: }; private: - ShadowCastingSetting shadow_casting_setting; + ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON; Ref<Material> material_override; - float lod_min_distance; - float lod_max_distance; - float lod_min_hysteresis; - float lod_max_hysteresis; + float lod_min_distance = 0.0; + float lod_max_distance = 0.0; + float lod_min_hysteresis = 0.0; + float lod_max_hysteresis = 0.0; - float lod_bias; + float lod_bias = 1.0; mutable HashMap<StringName, Variant> instance_uniforms; mutable HashMap<StringName, StringName> instance_uniform_property_remap; - float extra_cull_margin; - LightmapScale lightmap_scale; - GIMode gi_mode; + float extra_cull_margin = 0.0; + LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X; + GIMode gi_mode = GI_MODE_DISABLED; const StringName *_instance_uniform_get_remap(const StringName p_name) const; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index b99d753dde..17c8596e8f 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -1007,7 +1007,4 @@ Transform Voxelizer::get_to_cell_space_xform() const { } Voxelizer::Voxelizer() { - sorted = false; - color_scan_cell_width = 4; - bake_texture_size = 128; } diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index a0b581d625..87f949e7db 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -44,35 +44,25 @@ private: struct Cell { uint32_t children[8]; - float albedo[3]; //albedo in RGB24 - float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) - float normal[3]; - uint32_t used_sides; - float alpha; //used for upsampling - uint16_t x; - uint16_t y; - uint16_t z; - uint16_t level; + float albedo[3] = {}; //albedo in RGB24 + float emission[3] = {}; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) + float normal[3] = {}; + uint32_t used_sides = 0; + float alpha = 0.0; //used for upsampling + uint16_t x = 0; + uint16_t y = 0; + uint16_t z = 0; + uint16_t level = 0; Cell() { for (int i = 0; i < 8; i++) { children[i] = CHILD_EMPTY; } - - for (int i = 0; i < 3; i++) { - emission[i] = 0; - albedo[i] = 0; - normal[i] = 0; - } - alpha = 0; - used_sides = 0; - x = y = z = 0; - level = 0; } }; Vector<Cell> bake_cells; - int cell_subdiv; + int cell_subdiv = 0; struct CellSort { union { @@ -82,10 +72,10 @@ private: uint64_t x : 16; uint64_t level : 16; }; - uint64_t key; + uint64_t key = 0; }; - int32_t index; + int32_t index = 0; _FORCE_INLINE_ bool operator<(const CellSort &p_cell_sort) const { return key < p_cell_sort.key; @@ -101,16 +91,16 @@ private: Map<Ref<Material>, MaterialCache> material_cache; AABB original_bounds; AABB po2_bounds; - int axis_cell_size[3]; + int axis_cell_size[3] = {}; Transform to_cell_space; - int color_scan_cell_width; - int bake_texture_size; - float cell_size; + int color_scan_cell_width = 4; + int bake_texture_size = 128; + float cell_size = 0.0; - int max_original_cells; - int leaf_voxel_count; + int max_original_cells = 0; + int leaf_voxel_count = 0; Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add); MaterialCache _get_material_cache(Ref<Material> p_material); @@ -119,7 +109,7 @@ private: void _fixup_plot(int p_idx, int p_level); void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx); - bool sorted; + bool sorted = false; void _sort(); public: diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 41e1318b1f..15f562242f 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -311,14 +311,6 @@ AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() { for (int i = 0; i < MAX_BLEND_POINTS; i++) { blend_points[i].name = itos(i); } - blend_points_used = 0; - max_space = 1; - min_space = -1; - - snap = 0.1; - value_label = "value"; - - blend_position = "blend_position"; } AnimationNodeBlendSpace1D::~AnimationNodeBlendSpace1D() { diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index 6edbc4e319..8886e6c679 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -43,24 +43,24 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode { struct BlendPoint { StringName name; Ref<AnimationRootNode> node; - float position; + float position = 0.0; }; BlendPoint blend_points[MAX_BLEND_POINTS]; - int blend_points_used; + int blend_points_used = 0; - float max_space; - float min_space; + float max_space = 1.0; + float min_space = -1.0; - float snap; + float snap = 0.1; - String value_label; + String value_label = "value"; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _tree_changed(); - StringName blend_position; + StringName blend_position = "blend_position"; protected: virtual void _validate_property(PropertyInfo &property) const override; diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index c32cc82bd8..9c4bc107dd 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -437,7 +437,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { Vector2 blend_pos = get_parameter(blend_position); int closest = get_parameter(this->closest); float length_internal = get_parameter(this->length_internal); - float mind = 0; //time of min distance point + float mind = 0.0; //time of min distance point if (blend_mode == BLEND_MODE_INTERPOLATED) { if (triangles.size() == 0) { @@ -529,7 +529,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { } if (new_closest != closest && new_closest != -1) { - float from = 0; + float from = 0.0; if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) { //see how much animation remains from = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, true, 0.0, FILTER_IGNORE, false) - length_internal; @@ -665,18 +665,6 @@ AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() { for (int i = 0; i < MAX_BLEND_POINTS; i++) { blend_points[i].name = itos(i); } - auto_triangles = true; - blend_points_used = 0; - max_space = Vector2(1, 1); - min_space = Vector2(-1, -1); - snap = Vector2(0.1, 0.1); - x_label = "x"; - y_label = "y"; - trianges_dirty = false; - blend_position = "blend_position"; - closest = "closest"; - length_internal = "length_internal"; - blend_mode = BLEND_MODE_INTERPOLATED; } AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() { diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h index c74afcb8ce..65d09a550d 100644 --- a/scene/animation/animation_blend_space_2d.h +++ b/scene/animation/animation_blend_space_2d.h @@ -55,23 +55,23 @@ protected: }; BlendPoint blend_points[MAX_BLEND_POINTS]; - int blend_points_used; + int blend_points_used = 0; struct BlendTriangle { - int points[3]; + int points[3] = {}; }; Vector<BlendTriangle> triangles; - StringName blend_position; - StringName closest; - StringName length_internal; - Vector2 max_space; - Vector2 min_space; - Vector2 snap; - String x_label; - String y_label; - BlendMode blend_mode; + StringName blend_position = "blend_position"; + StringName closest = "closest"; + StringName length_internal = "length_internal"; + Vector2 max_space = Vector2(1, 1); + Vector2 min_space = Vector2(-1, -1); + Vector2 snap = Vector2(0.1, 0.1); + String x_label = "x"; + String y_label = "y"; + BlendMode blend_mode = BLEND_MODE_INTERPOLATED; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _set_triangles(const Vector<int> &p_triangles); @@ -79,8 +79,8 @@ protected: void _blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights); - bool auto_triangles; - bool trianges_dirty; + bool auto_triangles = true; + bool trianges_dirty = false; void _update_triangles(); void _queue_auto_triangles(); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 24ae01e9d8..79a1dc1ac0 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -34,7 +34,6 @@ void AnimationNodeAnimation::set_animation(const StringName &p_name) { animation = p_name; - _change_notify("animation"); } StringName AnimationNodeAnimation::get_animation() const { @@ -125,9 +124,6 @@ void AnimationNodeAnimation::_bind_methods() { } AnimationNodeAnimation::AnimationNodeAnimation() { - last_version = 0; - skip = false; - time = "time"; } //////////////////////////////////////////////////////// @@ -346,21 +342,6 @@ void AnimationNodeOneShot::_bind_methods() { AnimationNodeOneShot::AnimationNodeOneShot() { add_input("in"); add_input("shot"); - - fade_in = 0.1; - fade_out = 0.1; - autorestart = false; - autorestart_delay = 1; - autorestart_random_delay = 0; - - mix = MIX_MODE_BLEND; - sync = false; - - active = "active"; - prev_active = "prev_active"; - time = "time"; - remaining = "remaining"; - time_to_restart = "time_to_restart"; } //////////////////////////////////////////////// @@ -405,10 +386,8 @@ void AnimationNodeAdd2::_bind_methods() { } AnimationNodeAdd2::AnimationNodeAdd2() { - add_amount = "add_amount"; add_input("in"); add_input("add"); - sync = false; } //////////////////////////////////////////////// @@ -454,11 +433,9 @@ void AnimationNodeAdd3::_bind_methods() { } AnimationNodeAdd3::AnimationNodeAdd3() { - add_amount = "add_amount"; add_input("-add"); add_input("in"); add_input("+add"); - sync = false; } ///////////////////////////////////////////// @@ -504,10 +481,8 @@ void AnimationNodeBlend2::_bind_methods() { } AnimationNodeBlend2::AnimationNodeBlend2() { - blend_amount = "blend_amount"; add_input("in"); add_input("blend"); - sync = false; } ////////////////////////////////////// @@ -583,7 +558,6 @@ void AnimationNodeTimeScale::_bind_methods() { } AnimationNodeTimeScale::AnimationNodeTimeScale() { - scale = "scale"; add_input("in"); } @@ -608,7 +582,6 @@ float AnimationNodeTimeSeek::process(float p_time, bool p_seek) { } else if (seek_pos >= 0) { float ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false); set_parameter(this->seek_pos, -1.0); //reset - _change_notify("seek_pos"); return ret; } else { return blend_input(0, p_time, false, 1.0, FILTER_IGNORE, false); @@ -620,7 +593,6 @@ void AnimationNodeTimeSeek::_bind_methods() { AnimationNodeTimeSeek::AnimationNodeTimeSeek() { add_input("in"); - seek_pos = "seek_position"; } ///////////////////////////////////////////////// @@ -728,7 +700,7 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) { return 0; } - float rem = 0; + float rem = 0.0; if (prev < 0) { // process current animation, check for transition @@ -811,16 +783,7 @@ void AnimationNodeTransition::_bind_methods() { } AnimationNodeTransition::AnimationNodeTransition() { - prev_xfading = "prev_xfading"; - prev = "prev"; - time = "time"; - current = "current"; - prev_current = "prev_current"; - xfade = 0.0; - - enabled_inputs = 0; for (int i = 0; i < MAX_INPUTS; i++) { - inputs[i].auto_advance = false; inputs[i].name = "state " + itos(i); } } @@ -1158,6 +1121,13 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } +void AnimationNodeBlendTree::reset_state() { + graph_offset = Vector2(); + nodes.clear(); + emit_changed(); + emit_signal("tree_changed"); +} + void AnimationNodeBlendTree::_tree_changed() { emit_signal("tree_changed"); } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 45a9f2e7e1..d82658c8c2 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -37,10 +37,10 @@ class AnimationNodeAnimation : public AnimationRootNode { GDCLASS(AnimationNodeAnimation, AnimationRootNode); StringName animation; - StringName time; + StringName time = "time"; - uint64_t last_version; - bool skip; + uint64_t last_version = 0; + bool skip = false; protected: void _validate_property(PropertyInfo &property) const override; @@ -71,26 +71,26 @@ public: }; private: - float fade_in; - float fade_out; + float fade_in = 0.1; + float fade_out = 0.1; - bool autorestart; - float autorestart_delay; - float autorestart_random_delay; - MixMode mix; + bool autorestart = false; + float autorestart_delay = 1.0; + float autorestart_random_delay = 0.0; + MixMode mix = MIX_MODE_BLEND; - bool sync; + bool sync = false; /* bool active; bool do_start; float time; float remaining;*/ - StringName active; - StringName prev_active; - StringName time; - StringName remaining; - StringName time_to_restart; + StringName active = "active"; + StringName prev_active = "prev_active"; + StringName time = "time"; + StringName remaining = "remaining"; + StringName time_to_restart = "time_to_restart"; protected: static void _bind_methods(); @@ -132,8 +132,8 @@ VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode) class AnimationNodeAdd2 : public AnimationNode { GDCLASS(AnimationNodeAdd2, AnimationNode); - StringName add_amount; - bool sync; + StringName add_amount = "add_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -156,8 +156,8 @@ public: class AnimationNodeAdd3 : public AnimationNode { GDCLASS(AnimationNodeAdd3, AnimationNode); - StringName add_amount; - bool sync; + StringName add_amount = "add_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -180,8 +180,8 @@ public: class AnimationNodeBlend2 : public AnimationNode { GDCLASS(AnimationNodeBlend2, AnimationNode); - StringName blend_amount; - bool sync; + StringName blend_amount = "blend_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -225,7 +225,7 @@ public: class AnimationNodeTimeScale : public AnimationNode { GDCLASS(AnimationNodeTimeScale, AnimationNode); - StringName scale; + StringName scale = "scale"; protected: static void _bind_methods(); @@ -244,7 +244,7 @@ public: class AnimationNodeTimeSeek : public AnimationNode { GDCLASS(AnimationNodeTimeSeek, AnimationNode); - StringName seek_pos; + StringName seek_pos = "seek_position"; protected: static void _bind_methods(); @@ -268,12 +268,11 @@ class AnimationNodeTransition : public AnimationNode { }; struct InputData { String name; - bool auto_advance; - InputData() { auto_advance = false; } + bool auto_advance = false; }; InputData inputs[MAX_INPUTS]; - int enabled_inputs; + int enabled_inputs = 0; /* float prev_xfading; @@ -282,13 +281,13 @@ class AnimationNodeTransition : public AnimationNode { int current; int prev_current; */ - StringName prev_xfading; - StringName prev; - StringName time; - StringName current; - StringName prev_current; + StringName prev_xfading = "prev_xfading"; + StringName prev = "prev"; + StringName time = "time"; + StringName current = "current"; + StringName prev_current = "prev_current"; - float xfade; + float xfade = 0.0; void _update_inputs(); @@ -352,6 +351,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: enum ConnectionError { CONNECTION_OK, @@ -381,7 +382,7 @@ public: struct NodeConnection { StringName input_node; - int input_index; + int input_index = 0; StringName output_node; }; diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index 6ef2da6977..689acdd57b 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -308,7 +308,4 @@ void AnimationCache::set_root(Node *p_root) { } AnimationCache::AnimationCache() { - root = nullptr; - cache_dirty = true; - cache_valid = false; } diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h index 484b710b06..07c9d09ae0 100644 --- a/scene/animation/animation_cache.h +++ b/scene/animation/animation_cache.h @@ -39,31 +39,23 @@ class AnimationCache : public Object { struct Path { RES resource; - Object *object; - Skeleton3D *skeleton; // haxor - Node *node; - Node3D *spatial; + Object *object = nullptr; + Skeleton3D *skeleton = nullptr; // haxor + Node *node = nullptr; + Node3D *spatial = nullptr; - int bone_idx; + int bone_idx = -1; Vector<StringName> subpath; - bool valid; - Path() { - object = nullptr; - skeleton = nullptr; - node = nullptr; - bone_idx = -1; - valid = false; - spatial = nullptr; - } + bool valid = false; }; Set<Node *> connected_nodes; Vector<Path> path_cache; - Node *root; + Node *root = nullptr; Ref<Animation> animation; - bool cache_dirty; - bool cache_valid; + bool cache_dirty = true; + bool cache_valid = false; void _node_exit_tree(Node *p_node); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index ef9f531f04..71de3635f9 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -130,11 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() { } AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() { - switch_mode = SWITCH_MODE_IMMEDIATE; - auto_advance = false; - xfade = 0; - disabled = false; - priority = 1; } //////////////////////////////////////////////////////// @@ -398,7 +393,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st //find next StringName next; - float next_xfade = 0; + float next_xfade = 0.0; AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE; if (path.size()) { @@ -502,16 +497,6 @@ void AnimationNodeStateMachinePlayback::_bind_methods() { AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() { set_local_to_scene(true); //only one per instanced scene - - playing = false; - len_current = 0; - fading_time = 0; - stop_request = false; - len_total = 0.0; - pos_current = 0.0; - loops_current = 0; - fading_pos = 0.0; - start_request_travel = false; } /////////////////////////////////////////////////////// @@ -929,6 +914,18 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } +void AnimationNodeStateMachine::reset_state() { + states.clear(); + transitions.clear(); + playback = "playback"; + start_node = StringName(); + end_node = StringName(); + graph_offset = Vector2(); + + emit_changed(); + emit_signal("tree_changed"); +} + void AnimationNodeStateMachine::set_node_position(const StringName &p_name, const Vector2 &p_position) { ERR_FAIL_COND(!states.has(p_name)); states[p_name].position = p_position; @@ -975,5 +972,4 @@ void AnimationNodeStateMachine::_bind_methods() { } AnimationNodeStateMachine::AnimationNodeStateMachine() { - playback = "playback"; } diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index daeb2fabaa..9c1bca63c3 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -44,13 +44,13 @@ public: }; private: - SwitchMode switch_mode; - bool auto_advance; + SwitchMode switch_mode = SWITCH_MODE_IMMEDIATE; + bool auto_advance = false; StringName advance_condition; StringName advance_condition_name; - float xfade; - bool disabled; - int priority; + float xfade = 0.0; + bool disabled = false; + int priority = 1; protected: static void _bind_methods(); @@ -89,28 +89,28 @@ class AnimationNodeStateMachinePlayback : public Resource { friend class AnimationNodeStateMachine; struct AStarCost { - float distance; + float distance = 0.0; StringName prev; }; - float len_total; + float len_total = 0.0; - float len_current; - float pos_current; - int loops_current; + float len_current = 0.0; + float pos_current = 0.0; + int loops_current = 0; StringName current; StringName fading_from; - float fading_time; - float fading_pos; + float fading_time = 0.0; + float fading_pos = 0.0; Vector<StringName> path; - bool playing; + bool playing = false; StringName start_request; - bool start_request_travel; - bool stop_request; + bool start_request_travel = false; + bool stop_request = false; bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel); @@ -154,7 +154,7 @@ private: Vector<Transition> transitions; - StringName playback; + StringName playback = "playback"; StringName start_node; StringName end_node; @@ -171,6 +171,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: virtual void get_parameter_list(List<PropertyInfo> *r_list) const override; virtual Variant get_parameter_default_value(const StringName &p_parameter) const override; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 8e50c733ae..c6fa55b76e 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -229,13 +229,13 @@ void AnimationPlayer::_notification(int p_what) { } } -void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { +void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_override) { // Already cached? if (p_anim->node_cache.size() == p_anim->animation->get_track_count()) { return; } - Node *parent = get_node(root); + Node *parent = p_root_override ? p_root_override : get_node(root); ERR_FAIL_COND(!parent); @@ -969,7 +969,7 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati } _ref_anim(p_animation); - _change_notify(); + notify_property_list_changed(); return OK; } @@ -981,7 +981,7 @@ void AnimationPlayer::remove_animation(const StringName &p_name) { animation_set.erase(p_name); clear_caches(); - _change_notify(); + notify_property_list_changed(); } void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { @@ -1039,7 +1039,7 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam } clear_caches(); - _change_notify(); + notify_property_list_changed(); } bool AnimationPlayer::has_animation(const StringName &p_name) const { @@ -1132,7 +1132,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float Playback &c = playback; if (c.current.from) { - float blend_time = 0; + float blend_time = 0.0; // find if it can blend BlendKey bk; bk.from = c.current.from->name; @@ -1497,13 +1497,13 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i } #ifdef TOOLS_ENABLED -Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values() { +Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_override) { Ref<AnimatedValuesBackup> backup; if (!playback.current.from) { return backup; } - _ensure_node_caches(playback.current.from); + _ensure_node_caches(playback.current.from, p_root_override); backup.instance(); for (int i = 0; i < playback.current.from->node_cache.size(); i++) { @@ -1560,10 +1560,11 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { AnimationPlayer *aux_player = memnew(AnimationPlayer); EditorNode::get_singleton()->add_child(aux_player); - aux_player->set_root(aux_player->get_path_to(root_node)); aux_player->add_animation("RESET", reset_anim); aux_player->set_assigned_animation("RESET"); - Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(); + // Forcing the use of the original root because the scene where original player belongs may be not the active one + Node *root = get_node(get_root()); + Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root); aux_player->seek(0.0f, true); aux_player->queue_delete(); @@ -1677,23 +1678,7 @@ void AnimationPlayer::_bind_methods() { } AnimationPlayer::AnimationPlayer() { - accum_pass = 1; - cache_update_size = 0; - cache_update_prop_size = 0; - cache_update_bezier_size = 0; - speed_scale = 1; - end_reached = false; - end_notify = false; - reset_on_save = true; - animation_process_mode = ANIMATION_PROCESS_IDLE; - method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; - processing = false; - default_blend_time = 0; root = SceneStringNames::get_singleton()->path_pp; - playing = false; - active = true; - playback.seeked = false; - playback.started = false; } AnimationPlayer::~AnimationPlayer() { diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 4532825f5a..f2774cb395 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -41,9 +41,9 @@ class AnimatedValuesBackup : public Reference { GDCLASS(AnimatedValuesBackup, Reference); struct Entry { - Object *object; + Object *object = nullptr; Vector<StringName> subpath; // Unused if bone - int bone_idx; // -1 if not a bone + int bone_idx = -1; // -1 if not a bone Variant value; }; Vector<Entry> entries; @@ -118,8 +118,6 @@ private: Variant value_accum; uint64_t accum_pass = 0; Variant capture; - - PropertyAnim() {} }; Map<StringName, PropertyAnim> property_anim; @@ -130,8 +128,6 @@ private: float bezier_accum = 0.0; Object *object = nullptr; uint64_t accum_pass = 0; - - BezierAnim() {} }; Map<StringName, BezierAnim> bezier_anim; @@ -141,7 +137,7 @@ private: struct TrackNodeCacheKey { ObjectID id; - int bone_idx; + int bone_idx = -1; inline bool operator<(const TrackNodeCacheKey &p_right) const { if (id == p_right.id) { @@ -155,16 +151,16 @@ private: Map<TrackNodeCacheKey, TrackNodeCache> node_cache_map; TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX]; - int cache_update_size; + int cache_update_size = 0; TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX]; - int cache_update_prop_size; + int cache_update_prop_size = 0; TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX]; - int cache_update_bezier_size; + int cache_update_bezier_size = 0; Set<TrackNodeCache *> playing_caches; - uint64_t accum_pass; - float speed_scale; - float default_blend_time; + uint64_t accum_pass = 1; + float speed_scale = 1.0; + float default_blend_time = 0.0; struct AnimationData { String name; @@ -183,54 +179,43 @@ private: Map<BlendKey, float> blend_times; struct PlaybackData { - AnimationData *from; - float pos; - float speed_scale; - - PlaybackData() { - pos = 0; - speed_scale = 1.0; - from = nullptr; - } + AnimationData *from = nullptr; + float pos = 0.0; + float speed_scale = 1.0; }; struct Blend { PlaybackData data; - float blend_time; - float blend_left; - - Blend() { - blend_left = 0; - blend_time = 0; - } + float blend_time = 0.0; + float blend_left = 0.0; }; struct Playback { List<Blend> blend; PlaybackData current; StringName assigned; - bool seeked; - bool started; + bool seeked = false; + bool started = false; } playback; List<StringName> queued; - bool end_reached; - bool end_notify; + bool end_reached = false; + bool end_notify = false; String autoplay; - bool reset_on_save; - AnimationProcessMode animation_process_mode; - AnimationMethodCallMode method_call_mode; - bool processing; - bool active; + bool reset_on_save = true; + AnimationProcessMode animation_process_mode = ANIMATION_PROCESS_IDLE; + AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool processing = false; + bool active = true; NodePath root; void _animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false); - void _ensure_node_caches(AnimationData *p_anim); + void _ensure_node_caches(AnimationData *p_anim, Node *p_root_override = nullptr); void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started); void _animation_process2(float p_delta, bool p_started); void _animation_update_transforms(); @@ -257,7 +242,7 @@ private: void _set_process(bool p_process, bool p_force = false); - bool playing; + bool playing = false; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -334,7 +319,7 @@ public: void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; #ifdef TOOLS_ENABLED - Ref<AnimatedValuesBackup> backup_animated_values(); + Ref<AnimatedValuesBackup> backup_animated_values(Node *p_root_override = nullptr); Ref<AnimatedValuesBackup> apply_reset(bool p_user_initiated = false); bool can_apply_reset() const; #endif diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index e6abbc0c7a..c0da35d803 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -158,7 +158,7 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p Ref<AnimationNode> node = blend_tree->get_node(node_name); //inputs.write[p_input].last_pass = state->last_pass; - float activity = 0; + float activity = 0.0; float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity); Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path); @@ -441,9 +441,6 @@ void AnimationNode::_bind_methods() { } AnimationNode::AnimationNode() { - state = nullptr; - parent = nullptr; - filter_enabled = false; } //////////////////// @@ -820,6 +817,7 @@ void AnimationTree::_process_graph(float p_delta) { Ref<Animation> a = as.animation; float time = as.time; float delta = as.delta; + float weight = as.blend; bool seeked = as.seeked; for (int i = 0; i < a->get_track_count(); i++) { @@ -839,7 +837,7 @@ void AnimationTree::_process_graph(float p_delta) { ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count); - float blend = (*as.track_blends)[blend_idx]; + float blend = (*as.track_blends)[blend_idx] * weight; if (blend < CMP_EPSILON) { continue; //nothing to blend @@ -1396,7 +1394,7 @@ void AnimationTree::_update_properties() { properties_dirty = false; - _change_notify(); + notify_property_list_changed(); } bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) { @@ -1406,9 +1404,6 @@ bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) { if (property_map.has(p_name)) { property_map[p_name] = p_value; -#ifdef TOOLS_ENABLED - _change_notify(p_name.operator String().utf8().get_data()); -#endif return true; } @@ -1506,13 +1501,6 @@ void AnimationTree::_bind_methods() { } AnimationTree::AnimationTree() { - process_mode = ANIMATION_PROCESS_IDLE; - active = false; - cache_valid = false; - setup_pass = 1; - process_pass = 1; - started = true; - properties_dirty = true; } AnimationTree::~AnimationTree() { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index a0171e617b..0f78b1f0e2 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -63,26 +63,26 @@ public: struct AnimationState { Ref<Animation> animation; - float time; - float delta; - const Vector<float> *track_blends; - float blend; - bool seeked; + float time = 0.0; + float delta = 0.0; + const Vector<float> *track_blends = nullptr; + float blend = 0.0; + bool seeked = false; }; struct State { - int track_count; + int track_count = 0; HashMap<NodePath, int> track_map; List<AnimationState> animation_states; - bool valid; - AnimationPlayer *player; - AnimationTree *tree; + bool valid = false; + AnimationPlayer *player = nullptr; + AnimationTree *tree = nullptr; String invalid_reasons; - uint64_t last_pass; + uint64_t last_pass = 0; }; Vector<float> blends; - State *state; + State *state = nullptr; float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections); void _pre_update_animations(HashMap<NodePath, int> *track_map); @@ -90,10 +90,10 @@ public: //all this is temporary StringName base_path; Vector<StringName> connections; - AnimationNode *parent; + AnimationNode *parent = nullptr; HashMap<NodePath, bool> filter; - bool filter_enabled; + bool filter_enabled = false; Array _get_filters() const; void _set_filters(const Array &p_filters); @@ -171,36 +171,29 @@ public: private: struct TrackCache { - bool root_motion; - uint64_t setup_pass; - uint64_t process_pass; - Animation::TrackType type; - Object *object; + bool root_motion = false; + uint64_t setup_pass = 0; + uint64_t process_pass = 0; + Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION; + Object *object = nullptr; ObjectID object_id; TrackCache() { - root_motion = false; - setup_pass = 0; - process_pass = 0; - object = nullptr; } virtual ~TrackCache() {} }; struct TrackCacheTransform : public TrackCache { - Node3D *spatial; - Skeleton3D *skeleton; - int bone_idx; + Node3D *spatial = nullptr; + Skeleton3D *skeleton = nullptr; + int bone_idx = -1; Vector3 loc; Quat rot; - float rot_blend_accum; + float rot_blend_accum = 0.0; Vector3 scale; TrackCacheTransform() { type = Animation::TYPE_TRANSFORM; - spatial = nullptr; - bone_idx = -1; - skeleton = nullptr; } }; @@ -215,33 +208,28 @@ private: }; struct TrackCacheBezier : public TrackCache { - float value; + float value = 0.0; Vector<StringName> subpath; TrackCacheBezier() { type = Animation::TYPE_BEZIER; - value = 0; } }; struct TrackCacheAudio : public TrackCache { - bool playing; - float start; - float len; + bool playing = false; + float start = 0.0; + float len = 0.0; TrackCacheAudio() { type = Animation::TYPE_AUDIO; - playing = false; - start = 0; - len = 0; } }; struct TrackCacheAnimation : public TrackCache { - bool playing; + bool playing = false; TrackCacheAnimation() { type = Animation::TYPE_ANIMATION; - playing = false; } }; @@ -250,12 +238,12 @@ private: Ref<AnimationNode> root; - AnimationProcessMode process_mode; - bool active; + AnimationProcessMode process_mode = ANIMATION_PROCESS_IDLE; + bool active = false; NodePath animation_player; AnimationNode::State state; - bool cache_valid; + bool cache_valid = false; void _node_removed(Node *p_node); void _caches_cleared(); @@ -263,16 +251,16 @@ private: bool _update_caches(AnimationPlayer *player); void _process_graph(float p_delta); - uint64_t setup_pass; - uint64_t process_pass; + uint64_t setup_pass = 1; + uint64_t process_pass = 1; - bool started; + bool started = true; NodePath root_motion_track; Transform root_motion_transform; friend class AnimationNode; - bool properties_dirty; + bool properties_dirty = true; void _tree_changed(); void _update_properties(); List<PropertyInfo> properties; @@ -280,8 +268,8 @@ private: HashMap<StringName, Variant> property_map; struct Activity { - uint64_t last_pass; - float activity; + uint64_t last_pass = 0; + float activity = 0.0; }; HashMap<StringName, Vector<Activity>> input_activity_map; diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 5fd936df8e..a4a1b02a4c 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -188,13 +188,9 @@ void RootMotionView::_bind_methods() { } RootMotionView::RootMotionView() { - zero_y = true; - radius = 10; - cell_size = 1; set_process_internal(true); immediate = RenderingServer::get_singleton()->immediate_create(); set_base(immediate); - color = Color(0.5, 0.5, 1.0); } RootMotionView::~RootMotionView() { diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index 063fb8feda..afcff6137f 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -39,12 +39,12 @@ class RootMotionView : public VisualInstance3D { public: RID immediate; NodePath path; - float cell_size; - float radius; - bool use_in_game; - Color color; - bool first; - bool zero_y; + float cell_size = 1.0; + float radius = 10.0; + bool use_in_game = false; + Color color = Color(0.5, 0.5, 1.0); + bool first = true; + bool zero_y = true; Transform accumulated; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 8bdb5c7447..62d03ea80c 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -1098,7 +1098,7 @@ void Tween::seek(real_t p_time) { real_t Tween::tell() const { // We want to grab the position of the furthest along tween pending_update++; - real_t pos = 0; + real_t pos = 0.0; // For each interpolation... for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { @@ -1122,7 +1122,7 @@ real_t Tween::get_runtime() const { pending_update++; // For each interpolation... - real_t runtime = 0; + real_t runtime = 0.0; for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { // Get the tween data and see if it's runtime is greater than the previous tweens const InterpolateData &data = E->get(); @@ -1789,12 +1789,6 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in } Tween::Tween() { - // Initialize tween attributes - tween_process_mode = TWEEN_PROCESS_IDLE; - repeat = false; - speed_scale = 1; - pending_update = 0; - uid = 0; } Tween::~Tween() { diff --git a/scene/animation/tween.h b/scene/animation/tween.h index c65a6f850f..88c02be0bc 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -79,11 +79,11 @@ private: }; struct InterpolateData { - bool active; - InterpolateType type; - bool finish; - bool call_deferred; - real_t elapsed; + bool active = false; + InterpolateType type = INTER_CALLBACK; + bool finish = false; + bool call_deferred = false; + real_t elapsed = 0.0; ObjectID id; Vector<StringName> key; StringName concatenated_key; @@ -92,33 +92,27 @@ private: Variant final_val; ObjectID target_id; Vector<StringName> target_key; - real_t duration; - TransitionType trans_type; - EaseType ease_type; - real_t delay; - int args; + real_t duration = 0.0; + TransitionType trans_type = TransitionType::TRANS_BACK; + EaseType ease_type = EaseType::EASE_COUNT; + real_t delay = 0.0; + int args = 0; Variant arg[5]; - int uid; - InterpolateData() { - active = false; - finish = false; - call_deferred = false; - uid = 0; - } + int uid = 0; }; String autoplay; - TweenProcessMode tween_process_mode; - bool repeat; - float speed_scale; - mutable int pending_update; - int uid; + TweenProcessMode tween_process_mode = TWEEN_PROCESS_IDLE; + bool repeat = false; + float speed_scale = 1.0; + mutable int pending_update = 0; + int uid = 0; List<InterpolateData> interpolates; struct PendingCommand { StringName key; - int args; + int args = 0; Variant arg[10]; }; List<PendingCommand> pending_commands; diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 4a9e146696..4f77734b79 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -344,7 +344,7 @@ void AudioStreamPlayer::_validate_property(PropertyInfo &property) const { } void AudioStreamPlayer::_bus_layout_changed() { - _change_notify(); + notify_property_list_changed(); } Ref<AudioStreamPlayback> AudioStreamPlayer::get_stream_playback() { @@ -402,18 +402,7 @@ void AudioStreamPlayer::_bind_methods() { } AudioStreamPlayer::AudioStreamPlayer() { - mix_volume_db = 0; - pitch_scale = 1.0; - volume_db = 0; - autoplay = false; - setseek = -1; - active = false; - stream_paused = false; - stream_paused_fade = false; - mix_target = MIX_TARGET_STEREO; fadeout_buffer.resize(512); - setstop = false; - use_fadeout = false; AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer::_bus_layout_changed)); } diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h index fa45a39682..ab98d41302 100644 --- a/scene/audio/audio_stream_player.h +++ b/scene/audio/audio_stream_player.h @@ -49,22 +49,22 @@ private: Ref<AudioStream> stream; Vector<AudioFrame> mix_buffer; Vector<AudioFrame> fadeout_buffer; - bool use_fadeout; - - volatile float setseek; - volatile bool active; - volatile bool setstop; - volatile bool stop_has_priority; - - float mix_volume_db; - float pitch_scale; - float volume_db; - bool autoplay; - bool stream_paused; - bool stream_paused_fade; + bool use_fadeout = false; + + volatile float setseek = -1.0; + volatile bool active = false; + volatile bool setstop = false; + volatile bool stop_has_priority = false; + + float mix_volume_db = 0.0; + float pitch_scale = 1.0; + float volume_db = 0.0; + bool autoplay = false; + bool stream_paused = false; + bool stream_paused_fade = false; StringName bus; - MixTarget mix_target; + MixTarget mix_target = MIX_TARGET_STEREO; void _mix_internal(bool p_fadeout); void _mix_audio(); diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index 51632446f8..9d54556187 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -77,7 +77,7 @@ public: class SceneDebuggerTree { public: struct RemoteNode { - int child_count; + int child_count = 0; String name; String type_name; ObjectID id; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 27e33be9d7..db13b9b11f 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -199,7 +199,6 @@ void BaseButton::set_disabled(bool p_disabled) { status.pressing_inside = false; } update(); - _change_notify("disabled"); } bool BaseButton::is_disabled() const { @@ -213,7 +212,6 @@ void BaseButton::set_pressed(bool p_pressed) { if (status.pressed == p_pressed) { return; } - _change_notify("pressed"); status.pressed = p_pressed; if (p_pressed) { @@ -448,18 +446,7 @@ void BaseButton::_bind_methods() { } BaseButton::BaseButton() { - toggle_mode = false; - shortcut_in_tooltip = true; - keep_pressed_outside = false; - status.pressed = false; - status.press_attempt = false; - status.hovering = false; - status.pressing_inside = false; - status.disabled = false; set_focus_mode(FOCUS_ALL); - action_mode = ACTION_MODE_BUTTON_RELEASE; - button_mask = BUTTON_MASK_LEFT; - shortcut_context = ObjectID(); } BaseButton::~BaseButton() { diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index b349b75761..d54d63cc39 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -45,21 +45,21 @@ public: }; private: - int button_mask; - bool toggle_mode; - bool shortcut_in_tooltip; - bool keep_pressed_outside; + int button_mask = BUTTON_MASK_LEFT; + bool toggle_mode = false; + bool shortcut_in_tooltip = true; + bool keep_pressed_outside = false; Ref<Shortcut> shortcut; ObjectID shortcut_context; - ActionMode action_mode; + ActionMode action_mode = ACTION_MODE_BUTTON_RELEASE; struct Status { - bool pressed; - bool hovering; - bool press_attempt; - bool pressing_inside; + bool pressed = false; + bool hovering = false; + bool press_attempt = false; + bool pressing_inside = false; - bool disabled; + bool disabled = false; } status; diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index a00d755c9c..c570438b6a 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -33,9 +33,9 @@ #include "margin_container.h" struct _MinSizeCache { - int min_size; - bool will_stretch; - int final_size; + int min_size = 0; + bool will_stretch = false; + int final_size = 0; }; void BoxContainer::_resort() { @@ -50,7 +50,7 @@ void BoxContainer::_resort() { int children_count = 0; int stretch_min = 0; int stretch_avail = 0; - float stretch_ratio_total = 0; + float stretch_ratio_total = 0.0; Map<Control *, _MinSizeCache> min_size_cache; for (int i = 0; i < get_child_count(); i++) { @@ -105,7 +105,7 @@ void BoxContainer::_resort() { has_stretched = true; bool refit_successful = true; //assume refit-test will go well - float error = 0; // Keep track of accumulated error in pixels + float error = 0.0; // Keep track of accumulated error in pixels for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -331,7 +331,6 @@ void BoxContainer::add_spacer(bool p_begin) { BoxContainer::BoxContainer(bool p_vertical) { vertical = p_vertical; - align = ALIGN_BEGIN; } void BoxContainer::_bind_methods() { diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index 8285c2b9a2..31050d1feb 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -44,8 +44,8 @@ public: }; private: - bool vertical; - AlignMode align; + bool vertical = false; + AlignMode align = ALIGN_BEGIN; void _resort(); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index f7c9583fbf..37bb17b47d 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -203,7 +203,7 @@ void Button::_notification(int p_what) { color_icon.a = 0.4; } - float icon_ofs_region = 0; + float icon_ofs_region = 0.0; if (rtl) { if (_internal_margin[SIDE_RIGHT] > 0) { icon_ofs_region = _internal_margin[SIDE_RIGHT] + get_theme_constant("hseparation"); @@ -306,10 +306,10 @@ void Button::_notification(int p_what) { Color font_outline_color = get_theme_color("font_outline_color"); int outline_size = get_theme_constant("outline_size"); if (outline_size > 0 && font_outline_color.a > 0) { - text_buf->draw_outline(ci, text_ofs.floor(), outline_size, font_outline_color); + text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color); } - text_buf->draw(ci, text_ofs.floor(), color); + text_buf->draw(ci, text_ofs, color); if (!_icon.is_null() && icon_region.size.width > 0) { draw_texture_rect_region(_icon, icon_region, Rect2(Point2(), _icon->get_size()), color_icon); @@ -338,7 +338,6 @@ void Button::set_text(const String &p_text) { _shape(); update(); - _change_notify("text"); minimum_size_changed(); } } @@ -399,7 +398,6 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) { if (icon != p_icon) { icon = p_icon; update(); - _change_notify("icon"); minimum_size_changed(); } } @@ -424,7 +422,6 @@ void Button::set_flat(bool p_flat) { if (flat != p_flat) { flat = p_flat; update(); - _change_notify("flat"); } } @@ -474,7 +471,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -544,16 +541,8 @@ Button::Button(const String &p_text) { text_buf.instance(); text_buf->set_flags(TextServer::BREAK_MANDATORY); - flat = false; - clip_text = false; - expand_icon = false; set_mouse_filter(MOUSE_FILTER_STOP); set_text(p_text); - align = ALIGN_CENTER; - - for (int i = 0; i < 4; i++) { - _internal_margin[i] = 0; - } } Button::~Button() { diff --git a/scene/gui/button.h b/scene/gui/button.h index d633fddc8a..d968f63f51 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -45,7 +45,7 @@ public: }; private: - bool flat; + bool flat = false; String text; String xl_text; Ref<TextParagraph> text_buf; @@ -55,10 +55,10 @@ private: TextDirection text_direction = TEXT_DIRECTION_AUTO; Ref<Texture2D> icon; - bool expand_icon; - bool clip_text; - TextAlign align; - float _internal_margin[4]; + bool expand_icon = false; + bool clip_text = false; + TextAlign align = ALIGN_CENTER; + float _internal_margin[4] = {}; void _shape(); diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index f2d1dee0fc..909516e7ef 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -95,6 +95,4 @@ void CenterContainer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_top_left"), "set_use_top_left", "is_using_top_left"); } -CenterContainer::CenterContainer() { - use_top_left = false; -} +CenterContainer::CenterContainer() {} diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h index ee8b2e0e48..0944f200fc 100644 --- a/scene/gui/center_container.h +++ b/scene/gui/center_container.h @@ -36,7 +36,7 @@ class CenterContainer : public Container { GDCLASS(CenterContainer, Container); - bool use_top_left; + bool use_top_left = false; protected: void _notification(int p_what); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 6c81ef0998..a3205c27a7 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -52,6 +52,7 @@ void ColorPicker::_notification(int p_what) { btn_pick->set_icon(get_theme_icon("screen_picker", "ColorPicker")); bt_add_preset->set_icon(get_theme_icon("add_preset")); + _update_controls(); _update_color(); #ifdef TOOLS_ENABLED @@ -718,17 +719,6 @@ void ColorPicker::_bind_methods() { ColorPicker::ColorPicker() : BoxContainer(true) { - updating = true; - edit_alpha = true; - text_is_constructor = false; - hsv_mode_enabled = false; - raw_mode_enabled = false; - deferred_mode_enabled = false; - changing_color = false; - presets_enabled = true; - presets_visible = true; - screen = nullptr; - HBoxContainer *hb_edit = memnew(HBoxContainer); add_child(hb_edit); hb_edit->set_v_size_flags(SIZE_EXPAND_FILL); @@ -1001,12 +991,5 @@ void ColorPickerButton::_bind_methods() { } ColorPickerButton::ColorPickerButton() { - // Initialization is now done deferred, - // this improves performance in the inspector as the color picker - // can be expensive to initialize. - picker = nullptr; - popup = nullptr; - edit_alpha = true; - set_toggle_mode(true); } diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 3695820a79..7915527bc0 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -46,7 +46,7 @@ class ColorPicker : public BoxContainer { GDCLASS(ColorPicker, BoxContainer); private: - Control *screen; + Control *screen = nullptr; Control *uv_edit; Control *w_edit; TextureRect *sample; @@ -64,20 +64,22 @@ private: Label *labels[4]; Button *text_type; LineEdit *c_text; - bool edit_alpha; + bool edit_alpha = true; Size2i ms; - bool text_is_constructor; - int presets_per_row; + bool text_is_constructor = false; + int presets_per_row = 0; Color color; - bool raw_mode_enabled; - bool hsv_mode_enabled; - bool deferred_mode_enabled; - bool updating; - bool changing_color; - bool presets_enabled; - bool presets_visible; - float h, s, v; + bool raw_mode_enabled = false; + bool hsv_mode_enabled = false; + bool deferred_mode_enabled = false; + bool updating = true; + bool changing_color = false; + bool presets_enabled = true; + bool presets_visible = true; + float h = 0.0; + float s = 0.0; + float v = 0.0; Color last_hsv; void _html_entered(const String &p_html); @@ -139,10 +141,14 @@ public: class ColorPickerButton : public Button { GDCLASS(ColorPickerButton, Button); - PopupPanel *popup; - ColorPicker *picker; + // Initialization is now done deferred, + // this improves performance in the inspector as the color picker + // can be expensive to initialize. + + PopupPanel *popup = nullptr; + ColorPicker *picker = nullptr; Color color; - bool edit_alpha; + bool edit_alpha = true; void _color_changed(const Color &p_color); void _modal_closed(); diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 03bade6702..2e6b798eea 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -180,7 +180,6 @@ void Container::_bind_methods() { } Container::Container() { - pending_sort = false; // All containers should let mouse events pass by default. set_mouse_filter(MOUSE_FILTER_PASS); } diff --git a/scene/gui/container.h b/scene/gui/container.h index 5e60ca04dc..a4f392a3ae 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -36,7 +36,7 @@ class Container : public Control { GDCLASS(Container, Control); - bool pending_sort; + bool pending_sort = false; void _sort_children(); void _child_minsize_changed(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 6b5d8cb658..cf75365b44 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1275,7 +1275,6 @@ void Control::_size_changed() { } if (pos_changed || size_changed) { item_rect_changed(size_changed); - _change_notify_offsets(); _notify_transform(); } @@ -1315,10 +1314,6 @@ void Control::set_anchor(Side p_side, float p_anchor, bool p_keep_offset, bool p } update(); - _change_notify("anchor_left"); - _change_notify("anchor_right"); - _change_notify("anchor_top"); - _change_notify("anchor_bottom"); } void Control::_set_anchor(Side p_side, float p_anchor) { @@ -1592,16 +1587,6 @@ float Control::get_anchor(Side p_side) const { return data.anchor[p_side]; } -void Control::_change_notify_offsets() { - // this avoids sending the whole object data again on a change - _change_notify("offset_left"); - _change_notify("offset_top"); - _change_notify("offset_right"); - _change_notify("offset_bottom"); - _change_notify("rect_position"); - _change_notify("rect_size"); -} - void Control::set_offset(Side p_side, float p_value) { ERR_FAIL_INDEX((int)p_side, 4); @@ -1699,10 +1684,6 @@ void Control::_set_position(const Size2 &p_point) { void Control::set_position(const Size2 &p_point, bool p_keep_offsets) { if (p_keep_offsets) { _compute_anchors(Rect2(p_point, data.size_cache), data.offset, data.anchor); - _change_notify("anchor_left"); - _change_notify("anchor_right"); - _change_notify("anchor_top"); - _change_notify("anchor_bottom"); } else { _compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset); } @@ -1736,10 +1717,6 @@ void Control::set_size(const Size2 &p_size, bool p_keep_offsets) { if (p_keep_offsets) { _compute_anchors(Rect2(data.pos_cache, new_size), data.offset, data.anchor); - _change_notify("anchor_left"); - _change_notify("anchor_right"); - _change_notify("anchor_top"); - _change_notify("anchor_bottom"); } else { _compute_offsets(Rect2(data.pos_cache, new_size), data.anchor, data.offset); } @@ -2577,7 +2554,6 @@ void Control::set_rotation(float p_radians) { data.rotation = p_radians; update(); _notify_transform(); - _change_notify("rect_rotation"); } float Control::get_rotation() const { @@ -2602,7 +2578,6 @@ void Control::set_pivot_offset(const Vector2 &p_pivot) { data.pivot_offset = p_pivot; update(); _notify_transform(); - _change_notify("rect_pivot_offset"); } Vector2 Control::get_pivot_offset() const { diff --git a/scene/gui/control.h b/scene/gui/control.h index ac2a1b35de..8b24781287 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -179,13 +179,13 @@ private: LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; - float rotation = 0; + float rotation = 0.0; Vector2 scale = Vector2(1, 1); Vector2 pivot_offset; int h_size_flags = SIZE_FILL; int v_size_flags = SIZE_FILL; - float expand = 1; + float expand = 1.0; Point2 custom_minimum_size; MouseFilter mouse_filter = MOUSE_FILTER_STOP; @@ -233,7 +233,6 @@ private: void _theme_changed(); - void _change_notify_offsets(); void _update_minimum_size(); void _update_scroll(); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 773c609a70..fdfbf9eafc 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -292,8 +292,6 @@ void AcceptDialog::set_swap_cancel_ok(bool p_swap) { } AcceptDialog::AcceptDialog() { - parent_visible = nullptr; - set_wrap_controls(true); set_visible(false); set_transient(true); @@ -325,7 +323,6 @@ AcceptDialog::AcceptDialog() { ok->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed)); - hide_on_ok = true; set_title(RTR("Alert!")); connect("window_input", callable_mp(this, &AcceptDialog::_input_from_window)); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index e450a3c30a..b072055d49 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -44,12 +44,12 @@ class LineEdit; class AcceptDialog : public Window { GDCLASS(AcceptDialog, Window); - Window *parent_visible; + Window *parent_visible = nullptr; Panel *bg; HBoxContainer *hbc; Label *label; Button *ok; - bool hide_on_ok; + bool hide_on_ok = true; void _custom_action(const String &p_action); void _update_child_rects(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 3a0350b9fb..7453324505 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -852,8 +852,6 @@ void FileDialog::set_default_show_hidden_files(bool p_show) { FileDialog::FileDialog() { show_hidden_files = default_show_hidden_files; - mode_overrides_title = true; - vbox = memnew(VBoxContainer); add_child(vbox); vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed)); @@ -925,7 +923,6 @@ FileDialog::FileDialog() { vbox->add_child(file_box); dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); - access = ACCESS_RESOURCES; _update_drives(); connect("confirmed", callable_mp(this, &FileDialog::_action_pressed)); @@ -967,7 +964,6 @@ FileDialog::FileDialog() { set_hide_on_ok(false); - invalidated = true; if (register_func) { register_func(this); } diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 626bb78d42..25b742c234 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -69,7 +69,7 @@ private: LineEdit *makedirname; Button *makedir; - Access access; + Access access = ACCESS_RESOURCES; //Button *action; VBoxContainer *vbox; FileMode mode; @@ -93,12 +93,12 @@ private: Vector<String> filters; - bool mode_overrides_title; + bool mode_overrides_title = true; static bool default_show_hidden_files; - bool show_hidden_files; + bool show_hidden_files = false; - bool invalidated; + bool invalidated = true; void update_dir(); void update_file_name(); diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index d18fff887d..36b383f16c 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -42,8 +42,6 @@ #endif GradientEdit::GradientEdit() { - grabbed = -1; - grabbing = false; set_focus_mode(FOCUS_ALL); popup = memnew(PopupPanel); diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index 189b33f563..eb7367d598 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -44,8 +44,8 @@ class GradientEdit : public Control { Ref<ImageTexture> checker; - bool grabbing; - int grabbed; + bool grabbing = false; + int grabbed = -1; Vector<Gradient::Point> points; void _draw_checker(int x, int y, int w, int h); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index bc87aabb2c..6e61950f10 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -385,6 +385,15 @@ void GraphEdit::_graph_node_moved(Node *p_gn) { connections_layer->update(); } +void GraphEdit::_graph_node_slot_updated(int p_index, Node *p_gn) { + GraphNode *gn = Object::cast_to<GraphNode>(p_gn); + ERR_FAIL_COND(!gn); + top_layer->update(); + minimap->update(); + update(); + connections_layer->update(); +} + void GraphEdit::add_child_notify(Node *p_child) { Control::add_child_notify(p_child); @@ -394,6 +403,7 @@ void GraphEdit::add_child_notify(Node *p_child) { if (gn) { gn->set_scale(Vector2(zoom, zoom)); gn->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved), varray(gn)); + gn->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated), varray(gn)); gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised), varray(gn)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update)); gn->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update)); @@ -419,6 +429,7 @@ void GraphEdit::remove_child_notify(Node *p_child) { GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved)); + gn->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated)); gn->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised)); // In case of the whole GraphEdit being destroyed these references can already be freed. @@ -1593,7 +1604,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_valid_connection_type", "from_type", "to_type"), &GraphEdit::remove_valid_connection_type); ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type); - ClassDB::bind_method(D_METHOD("set_zoom", "p_zoom"), &GraphEdit::set_zoom); + ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom); ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom); ClassDB::bind_method(D_METHOD("set_snap", "pixels"), &GraphEdit::set_snap); @@ -1608,9 +1619,9 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_connection_lines_antialiased", "pixels"), &GraphEdit::set_connection_lines_antialiased); ClassDB::bind_method(D_METHOD("is_connection_lines_antialiased"), &GraphEdit::is_connection_lines_antialiased); - ClassDB::bind_method(D_METHOD("set_minimap_size", "p_size"), &GraphEdit::set_minimap_size); + ClassDB::bind_method(D_METHOD("set_minimap_size", "size"), &GraphEdit::set_minimap_size); ClassDB::bind_method(D_METHOD("get_minimap_size"), &GraphEdit::get_minimap_size); - ClassDB::bind_method(D_METHOD("set_minimap_opacity", "p_opacity"), &GraphEdit::set_minimap_opacity); + ClassDB::bind_method(D_METHOD("set_minimap_opacity", "opacity"), &GraphEdit::set_minimap_opacity); ClassDB::bind_method(D_METHOD("get_minimap_opacity"), &GraphEdit::get_minimap_opacity); ClassDB::bind_method(D_METHOD("set_minimap_enabled", "enable"), &GraphEdit::set_minimap_enabled); @@ -1657,8 +1668,6 @@ void GraphEdit::_bind_methods() { GraphEdit::GraphEdit() { set_focus_mode(FOCUS_ALL); - awaiting_scroll_offset_update = false; - top_layer = nullptr; top_layer = memnew(GraphEditFilter(this)); add_child(top_layer); top_layer->set_mouse_filter(MOUSE_FILTER_PASS); @@ -1681,13 +1690,6 @@ GraphEdit::GraphEdit() { v_scroll->set_name("_v_scroll"); top_layer->add_child(v_scroll); - updating = false; - connecting = false; - right_disconnects = false; - - box_selecting = false; - dragging = false; - //set large minmax so it can scroll even if not resized yet h_scroll->set_min(-10000); h_scroll->set_max(10000); @@ -1698,8 +1700,6 @@ GraphEdit::GraphEdit() { h_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved)); v_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved)); - zoom = 1; - zoom_hb = memnew(HBoxContainer); top_layer->add_child(zoom_hb); zoom_hb->set_position(Vector2(10, 10)); @@ -1768,7 +1768,5 @@ GraphEdit::GraphEdit() { minimap->set_offset(Side::SIDE_BOTTOM, -MINIMAP_OFFSET); minimap->connect("draw", callable_mp(this, &GraphEdit::_minimap_draw)); - setting_scroll_ofs = false; - just_disconnected = false; set_clip_contents(true); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 4525152bd5..8fdf975319 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -99,9 +99,9 @@ public: struct Connection { StringName from; StringName to; - int from_port; - int to_port; - float activity; + int from_port = 0; + int to_port = 0; + float activity = 0.0; }; private: @@ -121,41 +121,41 @@ private: HScrollBar *h_scroll; VScrollBar *v_scroll; - float port_grab_distance_horizontal; + float port_grab_distance_horizontal = 0.0; float port_grab_distance_vertical; - bool connecting; + bool connecting = false; String connecting_from; - bool connecting_out; - int connecting_index; - int connecting_type; + bool connecting_out = false; + int connecting_index = 0; + int connecting_type = 0; Color connecting_color; - bool connecting_target; + bool connecting_target = false; Vector2 connecting_to; String connecting_target_to; int connecting_target_index; - bool just_disconnected; - bool connecting_valid; + bool just_disconnected = false; + bool connecting_valid = false; Vector2 click_pos; - bool dragging; - bool just_selected; - bool moving_selection; + bool dragging = false; + bool just_selected = false; + bool moving_selection = false; Vector2 drag_accum; - float zoom; + float zoom = 1.0; - bool box_selecting; - bool box_selection_mode_additive; + bool box_selecting = false; + bool box_selection_mode_additive = false; Point2 box_selecting_from; Point2 box_selecting_to; Rect2 box_selecting_rect; List<GraphNode *> previus_selected; - bool setting_scroll_ofs; - bool right_disconnects; - bool updating; - bool awaiting_scroll_offset_update; + bool setting_scroll_ofs = false; + bool right_disconnects = false; + bool updating = false; + bool awaiting_scroll_offset_update = false; List<Connection> connections; float lines_thickness = 2.0f; @@ -167,6 +167,7 @@ private: void _graph_node_raised(Node *p_gn); void _graph_node_moved(Node *p_gn); + void _graph_node_slot_updated(int p_index, Node *p_gn); void _update_scroll(); void _scroll_moved(double); @@ -194,7 +195,7 @@ private: uint32_t type_a; uint32_t type_b; }; - uint64_t key; + uint64_t key = 0; }; bool operator<(const ConnType &p_type) const { diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 9f5c87377f..b615cdb266 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -51,7 +51,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -71,6 +71,8 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { si.enable_left = p_value; } else if (what == "left_type") { si.type_left = p_value; + } else if (what == "left_icon") { + si.custom_slot_left = p_value; } else if (what == "left_color") { si.color_left = p_value; } else if (what == "right_enabled") { @@ -79,11 +81,13 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { si.type_right = p_value; } else if (what == "right_color") { si.color_right = p_value; + } else if (what == "right_icon") { + si.custom_slot_right = p_value; } else { return false; } - set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right); + set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right, si.custom_slot_left, si.custom_slot_right); update(); return true; } @@ -120,12 +124,16 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const { r_ret = si.type_left; } else if (what == "left_color") { r_ret = si.color_left; + } else if (what == "left_icon") { + r_ret = si.custom_slot_left; } else if (what == "right_enabled") { r_ret = si.enable_right; } else if (what == "right_type") { r_ret = si.type_right; } else if (what == "right_color") { r_ret = si.color_right; + } else if (what == "right_icon") { + r_ret = si.custom_slot_right; } else { return false; } @@ -152,9 +160,11 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::BOOL, base + "left_enabled")); p_list->push_back(PropertyInfo(Variant::INT, base + "left_type")); p_list->push_back(PropertyInfo(Variant::COLOR, base + "left_color")); + p_list->push_back(PropertyInfo(Variant::OBJECT, base + "left_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); p_list->push_back(PropertyInfo(Variant::BOOL, base + "right_enabled")); p_list->push_back(PropertyInfo(Variant::INT, base + "right_type")); p_list->push_back(PropertyInfo(Variant::COLOR, base + "right_color")); + p_list->push_back(PropertyInfo(Variant::OBJECT, base + "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); idx++; } @@ -355,7 +365,9 @@ void GraphNode::_shape() { void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) { ERR_FAIL_COND(p_idx < 0); - if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1)) { + if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && + !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1) && + !p_custom_left.is_valid() && !p_custom_right.is_valid()) { slot_info.erase(p_idx); return; } @@ -372,6 +384,8 @@ void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const C slot_info[p_idx] = s; update(); connpos_dirty = true; + + emit_signal("slot_updated", p_idx); } void GraphNode::clear_slot(int p_idx) { @@ -472,7 +486,6 @@ void GraphNode::set_title(const String &p_title) { _shape(); update(); - _change_notify("title"); minimum_size_changed(); } @@ -826,6 +839,7 @@ void GraphNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay"); ADD_SIGNAL(MethodInfo("position_offset_changed")); + ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx"))); ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to"))); ADD_SIGNAL(MethodInfo("raise_request")); ADD_SIGNAL(MethodInfo("close_request")); @@ -838,12 +852,5 @@ void GraphNode::_bind_methods() { GraphNode::GraphNode() { title_buf.instance(); - overlay = OVERLAY_DISABLED; - show_close = false; - connpos_dirty = true; set_mouse_filter(MOUSE_FILTER_STOP); - comment = false; - resizable = false; - resizing = false; - selected = false; } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index cf66586e6b..1bc54dddb7 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -46,23 +46,14 @@ public: private: struct Slot { - bool enable_left; - int type_left; - Color color_left; - bool enable_right; - int type_right; - Color color_right; + bool enable_left = false; + int type_left = 0; + Color color_left = Color(1, 1, 1, 1); + bool enable_right = false; + int type_right = 0; + Color color_right = Color(1, 1, 1, 1); Ref<Texture2D> custom_slot_left; Ref<Texture2D> custom_slot_right; - - Slot() { - enable_left = false; - type_left = 0; - color_left = Color(1, 1, 1, 1); - enable_right = false; - type_right = 0; - color_right = Color(1, 1, 1, 1); - } }; String title; @@ -72,12 +63,12 @@ private: String language; TextDirection text_direction = TEXT_DIRECTION_AUTO; - bool show_close; + bool show_close = false; Vector2 position_offset; - bool comment; - bool resizable; + bool comment = false; + bool resizable = false; - bool resizing; + bool resizing = false; Vector2 resizing_from; Vector2 resizing_from_size; @@ -87,7 +78,7 @@ private: struct ConnCache { Vector2 pos; - int type; + int type = 0; Color color; }; @@ -96,16 +87,16 @@ private: Map<int, Slot> slot_info; - bool connpos_dirty; + bool connpos_dirty = true; void _connpos_update(); void _resort(); void _shape(); Vector2 drag_from; - bool selected; + bool selected = false; - Overlay overlay; + Overlay overlay = OVERLAY_DISABLED; protected: void _gui_input(const Ref<InputEvent> &p_ev); diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 11335db54a..541925a802 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -261,6 +261,4 @@ Size2 GridContainer::get_minimum_size() const { return ms; } -GridContainer::GridContainer() { - columns = 1; -} +GridContainer::GridContainer() {} diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index 8045c94b9a..9b43a5bc7e 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -36,7 +36,7 @@ class GridContainer : public Container { GDCLASS(GridContainer, Container); - int columns; + int columns = 1; protected: void _notification(int p_what); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 799b0ed612..d76284e333 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -899,7 +899,7 @@ void ItemList::_notification(int p_what) { } if (shape_changed) { - float max_column_width = 0; + float max_column_width = 0.0; //1- compute item minimum sizes for (int i = 0; i < items.size(); i++) { @@ -1194,7 +1194,6 @@ void ItemList::_notification(int p_what) { } if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) { - text_ofs = text_ofs.floor(); text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; @@ -1217,7 +1216,6 @@ void ItemList::_notification(int p_what) { text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2; } - text_ofs = text_ofs.floor(); text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; @@ -1617,34 +1615,12 @@ void ItemList::_bind_methods() { } ItemList::ItemList() { - current = -1; - - select_mode = SELECT_SINGLE; - icon_mode = ICON_MODE_LEFT; - - fixed_column_width = 0; - same_column_width = false; - max_text_lines = 1; - max_columns = 1; - auto_height = false; - auto_height_value = 0.0f; - scroll_bar = memnew(VScrollBar); add_child(scroll_bar); - shape_changed = true; scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed)); set_focus_mode(FOCUS_ALL); - current_columns = 1; - search_time_msec = 0; - ensure_selected_visible = false; - defer_select_single = -1; - allow_rmb_select = false; - allow_reselect = false; - do_autoscroll_to_bottom = false; - - icon_scale = 1.0f; set_clip_contents(true); } diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 4982a68071..86a0174a20 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -52,7 +52,7 @@ public: private: struct Item { Ref<Texture2D> icon; - bool icon_transposed; + bool icon_transposed = false; Rect2i icon_region; Color icon_modulate; Ref<Texture2D> tag_icon; @@ -62,10 +62,10 @@ private: String language; TextDirection text_direction = TEXT_DIRECTION_AUTO; - bool selectable; - bool selected; - bool disabled; - bool tooltip_enabled; + bool selectable = false; + bool selected = false; + bool disabled = false; + bool tooltip_enabled = false; Variant metadata; String tooltip; Color custom_fg; @@ -79,44 +79,44 @@ private: bool operator<(const Item &p_another) const { return text < p_another.text; } }; - int current; + int current = -1; - bool shape_changed; + bool shape_changed = true; - bool ensure_selected_visible; - bool same_column_width; + bool ensure_selected_visible = false; + bool same_column_width = false; - bool auto_height; - float auto_height_value; + bool auto_height = false; + float auto_height_value = 0.0; Vector<Item> items; Vector<int> separators; - SelectMode select_mode; - IconMode icon_mode; + SelectMode select_mode = SELECT_SINGLE; + IconMode icon_mode = ICON_MODE_LEFT; VScrollBar *scroll_bar; - uint64_t search_time_msec; + uint64_t search_time_msec = 0; String search_string; - int current_columns; - int fixed_column_width; - int max_text_lines; - int max_columns; + int current_columns = 1; + int fixed_column_width = 0; + int max_text_lines = 1; + int max_columns = 1; Size2 fixed_icon_size; Size2 max_item_size_cache; - int defer_select_single; + int defer_select_single = -1; - bool allow_rmb_select; + bool allow_rmb_select = false; - bool allow_reselect; + bool allow_reselect = false; - real_t icon_scale; + real_t icon_scale = 1.0; - bool do_autoscroll_to_bottom; + bool do_autoscroll_to_bottom = false; Array _get_items() const; void _set_items(const Array &p_items); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 8fc40955f0..453ecc802c 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -194,7 +194,7 @@ void Label::_notification(int p_what) { style->draw(ci, Rect2(Point2(0, 0), get_size())); - float total_h = 0; + float total_h = 0.0; int lines_visible = 0; // Get number of lines to fit to the height. @@ -391,7 +391,7 @@ int Label::get_visible_line_count() const { Ref<StyleBox> style = get_theme_stylebox("normal"); int line_spacing = get_theme_constant("line_spacing"); int lines_visible = 0; - float total_h = 0; + float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing; if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { @@ -538,7 +538,6 @@ void Label::set_visible_characters(int p_amount) { if (get_total_character_count() > 0) { percent_visible = (float)p_amount / (float)get_total_character_count(); } - _change_notify("percent_visible"); update(); } @@ -555,7 +554,6 @@ void Label::set_percent_visible(float p_percent) { visible_chars = get_total_character_count() * p_percent; percent_visible = p_percent; } - _change_notify("visible_chars"); update(); } @@ -610,7 +608,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } diff --git a/scene/gui/label.h b/scene/gui/label.h index 219c6af39e..032b4112e1 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -72,7 +72,7 @@ private: Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT; Array st_args; - float percent_visible = 1; + float percent_visible = 1.0; int visible_chars = -1; int lines_skipped = 0; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 51f780462f..654507b933 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1568,12 +1568,12 @@ Size2 LineEdit::get_minimum_size() const { Size2 min_size; // Minimum size of text. - int space_size = font->get_char_size('m', 0, font_size).x; - min_size.width = get_theme_constant("minimum_spaces") * space_size; + int em_space_size = font->get_char_size('M', 0, font_size).x; + min_size.width = get_theme_constant("minimum_character_width'") * em_space_size; if (expand_to_text_length) { // Add a space because some fonts are too exact, and because cursor needs a bit more when at the end. - min_size.width = MAX(min_size.width, full_width + space_size); + min_size.width = MAX(min_size.width, full_width + em_space_size); } min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM), font->get_height(font_size)); @@ -1958,7 +1958,6 @@ void LineEdit::_text_changed() { void LineEdit::_emit_text_change() { emit_signal("text_changed", text); - _change_notify("text"); text_changed_dirty = false; } @@ -2091,7 +2090,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -2264,9 +2263,6 @@ LineEdit::LineEdit() { text_rid = TS->create_shaped_text(); _create_undo_state(); - clear_button_status.press_attempt = false; - clear_button_status.pressing_inside = false; - deselect(); set_focus_mode(FOCUS_ALL); set_default_cursor_shape(CURSOR_IBEAM); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 6db7a78f61..457a709f5b 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -94,7 +94,7 @@ private: Point2 ime_selection; RID text_rid; - float full_width = 0; + float full_width = 0.0; bool selecting_enabled = true; @@ -129,19 +129,19 @@ private: Ref<Texture2D> right_icon; struct Selection { - int begin; - int end; - int cursor_start; - bool enabled; - bool creating; - bool doubleclick; - bool drag_attempt; + int begin = 0; + int end = 0; + int cursor_start = 0; + bool enabled = false; + bool creating = false; + bool doubleclick = false; + bool drag_attempt = false; } selection; struct TextOperation { - int cursor_pos; - int scroll_offset; - int cached_width; + int cursor_pos = 0; + int scroll_offset = 0; + int cached_width = 0; String text; }; List<TextOperation> undo_stack; diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 8e972438a5..c6706aba68 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -231,7 +231,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -294,7 +294,6 @@ void LinkButton::_bind_methods() { LinkButton::LinkButton() { text_buf.instance(); - underline_mode = UNDERLINE_MODE_ALWAYS; set_focus_mode(FOCUS_NONE); set_default_cursor_shape(CURSOR_POINTING_HAND); } diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 5ab6aba122..7eaa9f88b6 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -48,7 +48,7 @@ public: private: String text; Ref<TextLine> text_buf; - UnderlineMode underline_mode; + UnderlineMode underline_mode = UNDERLINE_MODE_ALWAYS; Dictionary opentype_features; String language; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 94cb5ef0f4..5acc7e808a 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -118,7 +118,6 @@ void MenuButton::set_disable_shortcuts(bool p_disabled) { } MenuButton::MenuButton() { - switch_on_hover = false; set_flat(true); set_toggle_mode(true); set_disable_shortcuts(false); diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index cd4ed5bcb2..fd9ae6021e 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -37,9 +37,9 @@ class MenuButton : public Button { GDCLASS(MenuButton, Button); - bool clicked; - bool switch_on_hover; - bool disable_shortcuts; + bool clicked = false; + bool switch_on_hover = false; + bool disable_shortcuts = false; PopupMenu *popup; Array _get_items() const; diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index c274eb5c10..29a38ad5e3 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -98,7 +98,6 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { */ minimum_size_changed(); emit_signal("texture_changed"); - _change_notify("texture"); } Ref<Texture2D> NinePatchRect::get_texture() const { @@ -110,20 +109,6 @@ void NinePatchRect::set_patch_margin(Side p_side, int p_size) { margin[p_side] = p_size; update(); minimum_size_changed(); - switch (p_side) { - case SIDE_LEFT: - _change_notify("patch_margin_left"); - break; - case SIDE_TOP: - _change_notify("patch_margin_top"); - break; - case SIDE_RIGHT: - _change_notify("patch_margin_right"); - break; - case SIDE_BOTTOM: - _change_notify("patch_margin_bottom"); - break; - } } int NinePatchRect::get_patch_margin(Side p_side) const { @@ -139,7 +124,6 @@ void NinePatchRect::set_region_rect(const Rect2 &p_region_rect) { region_rect = p_region_rect; item_rect_changed(); - _change_notify("region_rect"); } Rect2 NinePatchRect::get_region_rect() const { @@ -174,16 +158,7 @@ NinePatchRect::AxisStretchMode NinePatchRect::get_v_axis_stretch_mode() const { } NinePatchRect::NinePatchRect() { - margin[SIDE_LEFT] = 0; - margin[SIDE_RIGHT] = 0; - margin[SIDE_BOTTOM] = 0; - margin[SIDE_TOP] = 0; - set_mouse_filter(MOUSE_FILTER_IGNORE); - draw_center = true; - - axis_h = AXIS_STRETCH_MODE_STRETCH; - axis_v = AXIS_STRETCH_MODE_STRETCH; } NinePatchRect::~NinePatchRect() { diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h index fcf25018aa..f9a3f31fe5 100644 --- a/scene/gui/nine_patch_rect.h +++ b/scene/gui/nine_patch_rect.h @@ -43,12 +43,13 @@ public: AXIS_STRETCH_MODE_TILE_FIT, }; - bool draw_center; - int margin[4]; + bool draw_center = true; + int margin[4] = {}; Rect2 region_rect; Ref<Texture2D> texture; - AxisStretchMode axis_h, axis_v; + AxisStretchMode axis_h = AXIS_STRETCH_MODE_STRETCH; + AxisStretchMode axis_v = AXIS_STRETCH_MODE_STRETCH; protected: void _notification(int p_what); diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index e4c1f94b31..e52b6917be 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -336,7 +336,6 @@ void OptionButton::_bind_methods() { } OptionButton::OptionButton() { - current = -1; set_toggle_mode(true); set_text_align(ALIGN_LEFT); if (is_layout_rtl()) { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 9cb296baa9..d846e395ad 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -38,7 +38,7 @@ class OptionButton : public Button { GDCLASS(OptionButton, Button); PopupMenu *popup; - int current; + int current = -1; void _focused(int p_which); void _selected(int p_which); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index b2ebb91500..835f4c432f 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -52,8 +52,8 @@ Size2 PopupMenu::_get_contents_minimum_size() const { Size2 minsize = get_theme_stylebox("panel")->get_minimum_size(); // Accounts for margin in the margin container minsize.x += scroll_container->get_v_scrollbar()->get_size().width * 2; // Adds a buffer so that the scrollbar does not render over the top of content - float max_w = 0; - float icon_w = 0; + float max_w = 0.0; + float icon_w = 0.0; int check_w = MAX(get_theme_icon("checked")->get_width(), get_theme_icon("radio_checked")->get_width()) + hseparation; int accel_max_w = 0; bool has_check = false; @@ -1656,19 +1656,6 @@ PopupMenu::PopupMenu() { connect("window_input", callable_mp(this, &PopupMenu::_gui_input)); - mouse_over = -1; - submenu_over = -1; - initial_button_mask = 0; - during_grabbed_click = false; - - allow_search = true; - search_time_msec = 0; - search_string = ""; - - set_hide_on_item_selection(true); - set_hide_on_checkable_item_selection(true); - set_hide_on_multistate_item_selection(false); - submenu_timer = memnew(Timer); submenu_timer->set_wait_time(0.3); submenu_timer->set_one_shot(true); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index c050e61d50..184be42e95 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -51,28 +51,28 @@ class PopupMenu : public Popup { String language; Control::TextDirection text_direction = Control::TEXT_DIRECTION_AUTO; - bool checked; + bool checked = false; enum { CHECKABLE_TYPE_NONE, CHECKABLE_TYPE_CHECK_BOX, CHECKABLE_TYPE_RADIO_BUTTON, } checkable_type; - int max_states; - int state; - bool separator; - bool disabled; - bool dirty; - int id; + int max_states = 0; + int state = 0; + bool separator = false; + bool disabled = false; + bool dirty = true; + int id = 0; Variant metadata; String submenu; String tooltip; - uint32_t accel; - int _ofs_cache; - int _height_cache; - int h_ofs; + uint32_t accel = 0; + int _ofs_cache = 0; + int _height_cache = 0; + int h_ofs = 0; Ref<Shortcut> shortcut; - bool shortcut_is_global; - bool shortcut_is_disabled; + bool shortcut_is_global = false; + bool shortcut_is_disabled = false; // Returns (0,0) if icon is null. Size2 get_icon_size() const { @@ -82,19 +82,7 @@ class PopupMenu : public Popup { Item() { text_buf.instance(); accel_text_buf.instance(); - dirty = true; - checked = false; checkable_type = CHECKABLE_TYPE_NONE; - separator = false; - max_states = 0; - state = 0; - accel = 0; - disabled = false; - _ofs_cache = 0; - _height_cache = 0; - h_ofs = 0; - shortcut_is_global = false; - shortcut_is_disabled = false; } }; @@ -104,10 +92,10 @@ class PopupMenu : public Popup { Timer *submenu_timer; List<Rect2> autohide_areas; Vector<Item> items; - int initial_button_mask; - bool during_grabbed_click; - int mouse_over; - int submenu_over; + int initial_button_mask = 0; + bool during_grabbed_click = false; + int mouse_over = -1; + int submenu_over = -1; Rect2 parent_rect; String _get_accel_text(const Item &p_item) const; int _get_mouse_over(const Point2 &p_over) const; @@ -123,9 +111,9 @@ class PopupMenu : public Popup { void _submenu_timeout(); uint64_t popup_time_msec = 0; - bool hide_on_item_selection; - bool hide_on_checkable_item_selection; - bool hide_on_multistate_item_selection; + bool hide_on_item_selection = true; + bool hide_on_checkable_item_selection = true; + bool hide_on_multistate_item_selection = false; Vector2 moved; Array _get_items() const; @@ -136,9 +124,9 @@ class PopupMenu : public Popup { void _ref_shortcut(Ref<Shortcut> p_sc); void _unref_shortcut(Ref<Shortcut> p_sc); - bool allow_search; - uint64_t search_time_msec; - String search_string; + bool allow_search = true; + uint64_t search_time_msec = 0; + String search_string = ""; MarginContainer *margin_container; ScrollContainer *scroll_container; diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index 1b33cc6ffb..63174b2d7f 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -98,5 +98,4 @@ void ProgressBar::_bind_methods() { ProgressBar::ProgressBar() { set_v_size_flags(0); set_step(0.01); - percent_visible = true; } diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index 3317846108..fb6060d932 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -36,7 +36,7 @@ class ProgressBar : public Range { GDCLASS(ProgressBar, Range); - bool percent_visible; + bool percent_visible = true; protected: void _notification(int p_what); diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index 1e33ab0758..86b775e795 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -47,7 +47,6 @@ void Range::_value_changed_notify() { _value_changed(shared->val); emit_signal("value_changed", shared->val); update(); - _change_notify("value"); } void Range::Shared::emit_value_changed() { @@ -63,7 +62,6 @@ void Range::Shared::emit_value_changed() { void Range::_changed_notify(const char *p_what) { emit_signal("changed"); update(); - _change_notify(p_what); } void Range::Shared::emit_changed(const char *p_what) { @@ -314,17 +312,7 @@ bool Range::is_lesser_allowed() const { Range::Range() { shared = memnew(Shared); - shared->min = 0; - shared->max = 100; - shared->val = 0; - shared->step = 1; - shared->page = 0; shared->owners.insert(this); - shared->exp_ratio = false; - shared->allow_greater = false; - shared->allow_lesser = false; - - _rounded_values = false; } Range::~Range() { diff --git a/scene/gui/range.h b/scene/gui/range.h index 68ff46bd74..1072a109c6 100644 --- a/scene/gui/range.h +++ b/scene/gui/range.h @@ -37,11 +37,14 @@ class Range : public Control { GDCLASS(Range, Control); struct Shared { - double val, min, max; - double step, page; - bool exp_ratio; - bool allow_greater; - bool allow_lesser; + double val = 0.0; + double min = 0.0; + double max = 100.0; + double step = 1.0; + double page = 0.0; + bool exp_ratio = false; + bool allow_greater = false; + bool allow_lesser = false; Set<Range *> owners; void emit_value_changed(); void emit_changed(const char *p_what = ""); @@ -62,7 +65,7 @@ protected: static void _bind_methods(); - bool _rounded_values; + bool _rounded_values = false; public: void set_value(double p_val); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 6d5905aedc..07251cbed5 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -220,7 +220,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (tab_size > 0) { // Align inline tabs. Vector<float> tabs; - tabs.push_back(tab_size * p_base_font->get_char_size('m', 0, p_base_font_size).width); + tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width); l.text_buf->tab_align(tabs); } @@ -314,7 +314,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->rows.clear(); Vector2 offset; - float row_height = 0; + float row_height = 0.0; for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. @@ -392,7 +392,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> if (tab_size > 0) { // Align inline tabs. Vector<float> tabs; - tabs.push_back(tab_size * p_base_font->get_char_size('m', 0, p_base_font_size).width); + tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width); l.text_buf->tab_align(tabs); } @@ -553,7 +553,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> table->rows.clear(); Vector2 offset; - float row_height = 0; + float row_height = 0.0; for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames. @@ -1847,7 +1847,7 @@ int RichTextLabel::_find_list(Item *p_item, Vector<int> &r_index, Vector<ItemLis int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size) { Item *item = p_item; - float margin = 0; + float margin = 0.0; while (item) { if (item->type == ITEM_INDENT) { @@ -1859,7 +1859,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int if (font_size == -1) { font_size = p_base_font_size; } - margin += tab_size * font->get_char_size('m', 0, font_size).width; + margin += tab_size * font->get_char_size(' ', 0, font_size).width; } else if (item->type == ITEM_LIST) { Ref<Font> font = _find_font(item); @@ -1870,7 +1870,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int if (font_size == -1) { font_size = p_base_font_size; } - margin += tab_size * font->get_char_size('m', 0, font_size).width; + margin += tab_size * font->get_char_size(' ', 0, font_size).width; } item = item->parent; @@ -3722,7 +3722,6 @@ void RichTextLabel::set_percent_visible(float p_percent) { } main->first_invalid_line = 0; //invalidate ALL _validate_line_caches(main); - _change_notify("visible_characters"); update(); } } @@ -3948,7 +3947,6 @@ void RichTextLabel::set_visible_characters(int p_visible) { percent_visible = (float)p_visible / (float)total_char_count; } } - _change_notify("percent_visible"); update(); } @@ -4066,19 +4064,6 @@ RichTextLabel::RichTextLabel() { main->first_invalid_line = 0; main->first_resized_line = 0; current_frame = main; - tab_size = 4; - default_align = ALIGN_LEFT; - underline_meta = true; - meta_hovering = nullptr; - override_selected_font_color = false; - - scroll_visible = false; - scroll_follow = false; - scroll_following = false; - updating_scroll = false; - scroll_active = true; - scroll_w = 0; - scroll_updated = false; vscroll = memnew(VScrollBar); add_child(vscroll); @@ -4090,19 +4075,6 @@ RichTextLabel::RichTextLabel() { vscroll->connect("value_changed", callable_mp(this, &RichTextLabel::_scroll_changed)); vscroll->set_step(1); vscroll->hide(); - use_bbcode = false; - - selection.click_frame = nullptr; - selection.click_item = nullptr; - selection.active = false; - selection.enabled = false; - - visible_characters = -1; - percent_visible = 1; - visible_line_count = 0; - - fixed_width = -1; - fit_content_height = false; set_clip_contents(true); } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 037839dac7..84936221d5 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -147,9 +147,9 @@ private: struct ItemDropcap : public Item { String text; Ref<Font> font; - int font_size; + int font_size = 0; Color color; - int ol_size; + int ol_size = 0; Color ol_color; Rect2 dropcap_margins; ItemDropcap() { type = ITEM_DROPCAP; } @@ -232,11 +232,11 @@ private: struct ItemTable : public Item { struct Column { - bool expand; - int expand_ratio; - int min_width; - int max_width; - int width; + bool expand = false; + int expand_ratio = 0; + int min_width = 0; + int max_width = 0; + int width = 0; }; Vector<Column> columns; @@ -322,31 +322,31 @@ private: } }; - ItemFrame *main; - Item *current; - ItemFrame *current_frame; + ItemFrame *main = nullptr; + Item *current = nullptr; + ItemFrame *current_frame = nullptr; - VScrollBar *vscroll; + VScrollBar *vscroll = nullptr; - bool scroll_visible; - bool scroll_follow; - bool scroll_following; - bool scroll_active; - int scroll_w; - bool scroll_updated; - bool updating_scroll; + bool scroll_visible = false; + bool scroll_follow = false; + bool scroll_following = false; + bool scroll_active = true; + int scroll_w = 0; + bool scroll_updated = false; + bool updating_scroll = false; int current_idx = 1; int current_char_ofs = 0; - int visible_paragraph_count; - int visible_line_count; + int visible_paragraph_count = 0; + int visible_line_count = 0; - int tab_size; - bool underline_meta; - bool override_selected_font_color; + int tab_size = 4; + bool underline_meta = true; + bool override_selected_font_color = false; - Align default_align; + Align default_align = ALIGN_LEFT; - ItemMeta *meta_hovering; + ItemMeta *meta_hovering = nullptr; Variant current_meta; Vector<Ref<RichTextEffect>> custom_effects; @@ -363,29 +363,29 @@ private: Array st_args; struct Selection { - ItemFrame *click_frame; - int click_line; - Item *click_item; - int click_char; - - ItemFrame *from_frame; - int from_line; - Item *from_item; - int from_char; - - ItemFrame *to_frame; - int to_line; - Item *to_item; - int to_char; - - bool active; // anything selected? i.e. from, to, etc. valid? - bool enabled; // allow selections? + ItemFrame *click_frame = nullptr; + int click_line = 0; + Item *click_item = nullptr; + int click_char = 0; + + ItemFrame *from_frame = nullptr; + int from_line = 0; + Item *from_item = nullptr; + int from_char = 0; + + ItemFrame *to_frame = nullptr; + int to_line = 0; + Item *to_item = nullptr; + int to_char = 0; + + bool active = false; // anything selected? i.e. from, to, etc. valid? + bool enabled = false; // allow selections? }; Selection selection; - int visible_characters; - float percent_visible; + int visible_characters = -1; + float percent_visible = 1.0; void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr); @@ -434,12 +434,12 @@ private: Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier); virtual Dictionary parse_expressions_for_values(Vector<String> p_expressions); - bool use_bbcode; + bool use_bbcode = false; String bbcode; - int fixed_width; + int fixed_width = -1; - bool fit_content_height; + bool fit_content_height = false; protected: void _notification(int p_what); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 79a0de35fc..f2516e76a5 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -434,7 +434,7 @@ double ScrollBar::get_area_size() const { } double ScrollBar::get_area_offset() const { - double ofs = 0; + double ofs = 0.0; if (orientation == VERTICAL) { ofs += get_theme_stylebox("hscroll")->get_margin(SIDE_TOP); diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 7dd71cc269..24b3b33e82 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -47,14 +47,14 @@ class ScrollBar : public Range { Orientation orientation; Size2 size; - float custom_step = -1; + float custom_step = -1.0; HighlightStatus highlight = HIGHLIGHT_NONE; struct Drag { bool active = false; - float pos_at_click = 0; - float value_at_click = 0; + float pos_at_click = 0.0; + float value_at_click = 0.0; } drag; double get_grabber_size() const; @@ -73,14 +73,14 @@ class ScrollBar : public Range { Vector2 drag_node_accum; Vector2 drag_node_from; Vector2 last_drag_node_accum; - float last_drag_node_time; - float time_since_motion; + float last_drag_node_time = 0.0; + float time_since_motion = 0.0; bool drag_node_touching = false; bool drag_node_touching_deaccel = false; - bool click_handled; + bool click_handled = false; bool scrolling = false; - double target_scroll = 0; + double target_scroll = 0.0; bool smooth_scroll_enabled = false; void _drag_node_exit(); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 52feb2ab23..411891ece8 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -244,11 +244,11 @@ void ScrollContainer::_ensure_focused_visible(Control *p_control) { if (is_a_parent_of(p_control)) { Rect2 global_rect = get_global_rect(); Rect2 other_rect = p_control->get_global_rect(); - float right_margin = 0; + float right_margin = 0.0; if (v_scroll->is_visible()) { right_margin += v_scroll->get_size().x; } - float bottom_margin = 0; + float bottom_margin = 0.0; if (h_scroll->is_visible()) { bottom_margin += h_scroll->get_size().y; } @@ -624,15 +624,7 @@ ScrollContainer::ScrollContainer() { add_child(v_scroll); v_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved)); - drag_speed = Vector2(); - drag_touching = false; - drag_touching_deaccel = false; - beyond_deadzone = false; - scroll_h = true; - scroll_v = true; - deadzone = GLOBAL_GET("gui/common/default_scroll_deadzone"); - follow_focus = false; set_clip_contents(true); }; diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index 7e32cbed1c..9d3ce39345 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -50,18 +50,18 @@ class ScrollContainer : public Container { Vector2 drag_accum; Vector2 drag_from; Vector2 last_drag_accum; - float last_drag_time; - float time_since_motion; - bool drag_touching; - bool drag_touching_deaccel; - bool click_handled; - bool beyond_deadzone; - - bool scroll_h; - bool scroll_v; - - int deadzone; - bool follow_focus; + float last_drag_time = 0.0; + float time_since_motion = 0.0; + bool drag_touching = false; + bool drag_touching_deaccel = false; + bool click_handled = false; + bool beyond_deadzone = false; + + bool scroll_h = true; + bool scroll_v = true; + + int deadzone = 0; + bool follow_focus = false; void _cancel_drag(); diff --git a/scene/gui/separator.h b/scene/gui/separator.h index 1ac0f2c503..77162c68fa 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -36,7 +36,7 @@ class Separator : public Control { GDCLASS(Separator, Control); protected: - Orientation orientation; + Orientation orientation = Orientation::HORIZONTAL; void _notification(int p_what); public: diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 0edf1856de..8b07299e30 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -269,12 +269,5 @@ void Slider::_bind_methods() { Slider::Slider(Orientation p_orientation) { orientation = p_orientation; - mouse_inside = false; - grab.active = false; - ticks = 0; - ticks_on_borders = false; - custom_step = -1; - editable = true; - scrollable = true; set_focus_mode(FOCUS_ALL); } diff --git a/scene/gui/slider.h b/scene/gui/slider.h index 292931b7b5..65a4036cd1 100644 --- a/scene/gui/slider.h +++ b/scene/gui/slider.h @@ -37,23 +37,23 @@ class Slider : public Range { GDCLASS(Slider, Range); struct Grab { - int pos; - float uvalue; - bool active; + int pos = 0; + float uvalue = 0.0; + bool active = false; } grab; - int ticks; - bool mouse_inside; + int ticks = 0; + bool mouse_inside = false; Orientation orientation; - float custom_step; - bool editable; - bool scrollable; + float custom_step = -1.0; + bool editable = true; + bool scrollable = true; protected: void _gui_input(Ref<InputEvent> p_event); void _notification(int p_what); static void _bind_methods(); - bool ticks_on_borders; + bool ticks_on_borders = false; public: virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 32c878205e..2c9720e4b6 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -268,7 +268,6 @@ void SpinBox::_bind_methods() { } SpinBox::SpinBox() { - last_w = 0; line_edit = memnew(LineEdit); add_child(line_edit); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index a4e3d644e2..4c3adf30e8 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -39,7 +39,7 @@ class SpinBox : public Range { GDCLASS(SpinBox, Range); LineEdit *line_edit; - int last_w; + int last_w = 0; Timer *range_click_timer; void _range_click_timeout(); @@ -52,11 +52,11 @@ class SpinBox : public Range { void _line_edit_input(const Ref<InputEvent> &p_event); struct Drag { - float base_val = 0; + float base_val = 0.0; bool allowed = false; bool enabled = false; Vector2 capture_pos; - float diff_y = 0; + float diff_y = 0.0; } drag; void _line_edit_focus_exit(); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index d6f2df1d8c..d43e195df1 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -102,7 +102,7 @@ void SplitContainer::_resort() { middle_sep += clamped_split_offset; if (should_clamp_split_offset) { split_offset = clamped_split_offset; - _change_notify("split_offset"); + should_clamp_split_offset = false; } } @@ -359,12 +359,5 @@ void SplitContainer::_bind_methods() { } SplitContainer::SplitContainer(bool p_vertical) { - mouse_inside = false; - split_offset = 0; - should_clamp_split_offset = false; - middle_sep = 0; vertical = p_vertical; - dragging = false; - collapsed = false; - dragger_visibility = DRAGGER_VISIBLE; } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 46a6792206..6cb94d6ecf 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -44,16 +44,16 @@ public: }; private: - bool should_clamp_split_offset; - int split_offset; - int middle_sep; - bool vertical; - bool dragging; - int drag_from; - int drag_ofs; - bool collapsed; - DraggerVisibility dragger_visibility; - bool mouse_inside; + bool should_clamp_split_offset = false; + int split_offset = 0; + int middle_sep = 0; + bool vertical = false; + bool dragging = false; + int drag_from = 0; + int drag_ofs = 0; + bool collapsed = false; + DraggerVisibility dragger_visibility = DRAGGER_VISIBLE; + bool mouse_inside = false; Control *_getch(int p_idx) const; diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index 68eef0f96b..8ffdd269a4 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -203,8 +203,6 @@ void SubViewportContainer::_bind_methods() { } SubViewportContainer::SubViewportContainer() { - stretch = false; - shrink = 1; set_process_input(true); set_process_unhandled_input(true); } diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h index 91fc29d377..77cf4c16b3 100644 --- a/scene/gui/subviewport_container.h +++ b/scene/gui/subviewport_container.h @@ -36,8 +36,8 @@ class SubViewportContainer : public Container { GDCLASS(SubViewportContainer, Container); - bool stretch; - int shrink; + bool stretch = false; + int shrink = 1; protected: void _notification(int p_what); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 5acc789fbb..861f66628d 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -747,8 +747,6 @@ void TabContainer::set_current_tab(int p_current) { _repaint(); - _change_notify("current_tab"); - if (pending_previous == current) { emit_signal("tab_selected", current); } else { @@ -967,8 +965,6 @@ void TabContainer::set_tab_align(TabAlign p_align) { ERR_FAIL_INDEX(p_align, 3); align = p_align; update(); - - _change_notify("tab_align"); } TabContainer::TabAlign TabContainer::get_tab_align() const { @@ -1243,20 +1239,5 @@ void TabContainer::_bind_methods() { } TabContainer::TabContainer() { - first_tab_cache = 0; - last_tab_cache = 0; - buttons_visible_cache = false; - menu_hovered = false; - highlight_arrow = -1; - tabs_ofs_cache = 0; - current = 0; - previous = 0; - align = ALIGN_CENTER; - tabs_visible = true; - all_tabs_in_front = false; - drag_to_rearrange_enabled = false; - tabs_rearrange_group = -1; - use_hidden_tabs_for_min_size = false; - connect("mouse_exited", callable_mp(this, &TabContainer::_on_mouse_exited)); } diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 58742c5be8..4ed5255729 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -46,23 +46,23 @@ public: }; private: - int first_tab_cache; - int tabs_ofs_cache; - int last_tab_cache; - int current; - int previous; - bool tabs_visible; - bool all_tabs_in_front; - bool buttons_visible_cache; - bool menu_hovered; - int highlight_arrow; - TabAlign align; + int first_tab_cache = 0; + int tabs_ofs_cache = 0; + int last_tab_cache = 0; + int current = 0; + int previous = 0; + bool tabs_visible = true; + bool all_tabs_in_front = false; + bool buttons_visible_cache = false; + bool menu_hovered = false; + int highlight_arrow = -1; + TabAlign align = ALIGN_CENTER; Control *_get_tab(int p_idx) const; int _get_top_margin() const; mutable ObjectID popup_obj_id; - bool drag_to_rearrange_enabled; - bool use_hidden_tabs_for_min_size; - int tabs_rearrange_group; + bool drag_to_rearrange_enabled = false; + bool use_hidden_tabs_for_min_size = false; + int tabs_rearrange_group = -1; Vector<Ref<TextLine>> text_buf; Vector<Control *> _get_tabs() const; diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index c156b1e6f8..66f04e5569 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -481,7 +481,6 @@ void Tabs::set_current_tab(int p_current) { previous = current; current = p_current; - _change_notify("current_tab"); _update_cache(); update(); @@ -1137,27 +1136,5 @@ void Tabs::_bind_methods() { } Tabs::Tabs() { - current = 0; - previous = 0; - tab_align = ALIGN_CENTER; - rb_hover = -1; - rb_pressing = false; - highlight_arrow = -1; - - cb_hover = -1; - cb_pressing = false; - cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER; - offset = 0; - max_drawn_tab = 0; - - select_with_rmb = false; - - min_width = 0; - scrolling_enabled = true; - buttons_visible = false; - hover = -1; - drag_to_rearrange_enabled = false; - tabs_rearrange_group = -1; - connect("mouse_exited", callable_mp(this, &Tabs::_on_mouse_exited)); } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 4396981004..86877f4d80 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -63,42 +63,42 @@ private: Ref<TextLine> text_buf; Ref<Texture2D> icon; - int ofs_cache; - bool disabled; - int size_cache; - int size_text; - int x_cache; - int x_size_cache; + int ofs_cache = 0; + bool disabled = false; + int size_cache = 0; + int size_text = 0; + int x_cache = 0; + int x_size_cache = 0; Ref<Texture2D> right_button; Rect2 rb_rect; Rect2 cb_rect; }; - int offset; - int max_drawn_tab; - int highlight_arrow; - bool buttons_visible; - bool missing_right; + int offset = 0; + int max_drawn_tab = 0; + int highlight_arrow = -1; + bool buttons_visible = false; + bool missing_right = false; Vector<Tab> tabs; - int current; - int previous; + int current = 0; + int previous = 0; int _get_top_margin() const; - TabAlign tab_align; - int rb_hover; - bool rb_pressing; + TabAlign tab_align = ALIGN_CENTER; + int rb_hover = -1; + bool rb_pressing = false; - bool select_with_rmb; + bool select_with_rmb = false; - int cb_hover; - bool cb_pressing; - CloseButtonDisplayPolicy cb_displaypolicy; + int cb_hover = -1; + bool cb_pressing = false; + CloseButtonDisplayPolicy cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER; - int hover; // Hovered tab. - int min_width; - bool scrolling_enabled; - bool drag_to_rearrange_enabled; - int tabs_rearrange_group; + int hover = -1; // Hovered tab. + int min_width = 0; + bool scrolling_enabled = true; + bool drag_to_rearrange_enabled = false; + int tabs_rearrange_group = -1; int get_tab_width(int p_idx) const; void _ensure_no_over_offset(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index d5249e9ee5..3306a11dd0 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -202,7 +202,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ // Apply tab align. if (indent_size > 0) { Vector<float> tabs; - tabs.push_back(font->get_char_size('m', 0, font_size).width * indent_size); + tabs.push_back(font->get_char_size(' ', 0, font_size).width * indent_size); text.write[p_line].data_buf->tab_align(tabs); } } @@ -212,7 +212,7 @@ void TextEdit::Text::invalidate_all_lines() { text.write[i].data_buf->set_width(width); if (indent_size > 0) { Vector<float> tabs; - tabs.push_back(font->get_char_size('m', 0, font_size).width * indent_size); + tabs.push_back(font->get_char_size(' ', 0, font_size).width * indent_size); text.write[i].data_buf->tab_align(tabs); } } @@ -810,8 +810,8 @@ void TextEdit::_notification(int p_what) { } } + bool is_cursor_line_visible = false; Point2 cursor_pos; - int cursor_insert_offset_y = 0; // Get the highlighted words. String highlighted_text = get_selection_text(); @@ -1050,7 +1050,7 @@ void TextEdit::_notification(int p_what) { // Give visual indication of empty selected line. if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) { - int char_w = cache.font->get_char_size('m', 0, cache.font_size).width; + int char_w = cache.font->get_char_size(' ', 0, cache.font_size).width; if (rtl) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - xmargin_beg - ofs_x - char_w, ofs_y, char_w, row_height), cache.selection_color); } else { @@ -1238,6 +1238,7 @@ void TextEdit::_notification(int p_what) { } } + const int line_top_offset_y = ofs_y; ofs_y += (row_height - text_height) / 2; const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid); @@ -1327,7 +1328,9 @@ void TextEdit::_notification(int p_what) { int caret_width = 1; #endif if (cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) { - cursor_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); + is_cursor_line_visible = true; + cursor_pos.y = line_top_offset_y; + if (ime_text.length() == 0) { Rect2 l_caret, t_caret; TextServer::Direction l_dir, t_dir; @@ -1377,7 +1380,7 @@ void TextEdit::_notification(int p_what) { l_caret.size.y = h; } l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = cache.font->get_char_size('m', 0, cache.font_size).x; + l_caret.size.x = cache.font->get_char_size('M', 0, cache.font_size).x; draw_rect(l_caret, cache.caret_color, false); } @@ -1446,78 +1449,97 @@ void TextEdit::_notification(int p_what) { } bool completion_below = false; - if (completion_active && completion_options.size() > 0) { - // Code completion box. - Ref<StyleBox> csb = get_theme_stylebox("completion"); - int maxlines = get_theme_constant("completion_lines"); - int cmax_width = get_theme_constant("completion_max_width") * cache.font->get_char_size('x', 0, cache.font_size).x; - int scrollw = get_theme_constant("completion_scroll_width"); - Color scrollc = get_theme_color("completion_scroll_color"); + if (completion_active && is_cursor_line_visible && completion_options.size() > 0) { + // Completion panel + + const Ref<StyleBox> csb = get_theme_stylebox("completion"); + const int maxlines = get_theme_constant("completion_lines"); + const int cmax_width = get_theme_constant("completion_max_width") * cache.font->get_char_size('x', 0, cache.font_size).x; + const Color scrollc = get_theme_color("completion_scroll_color"); const int completion_options_size = completion_options.size(); - int lines = MIN(completion_options_size, maxlines); - int w = 0; - int h = lines * row_height; - int nofs = cache.font->get_string_size(completion_base, cache.font_size).width; + const int row_count = MIN(completion_options_size, maxlines); + const int completion_rows_height = row_count * row_height; + const int completion_base_width = cache.font->get_string_size(completion_base, cache.font_size).width; + int scroll_rectangle_width = get_theme_constant("completion_scroll_width"); + int width = 0; + + // Compute max width of the panel based on the longest completion option if (completion_options_size < 50) { for (int i = 0; i < completion_options_size; i++) { - int w2 = MIN(cache.font->get_string_size(completion_options[i].display, cache.font_size).x, cmax_width); - if (w2 > w) { - w = w2; + int line_width = MIN(cache.font->get_string_size(completion_options[i].display, cache.font_size).x, cmax_width); + if (line_width > width) { + width = line_width; } } } else { - w = cmax_width; + width = cmax_width; } // Add space for completion icons. const int icon_hsep = get_theme_constant("hseparation", "ItemList"); - Size2 icon_area_size(row_height, row_height); - w += icon_area_size.width + icon_hsep; + const Size2 icon_area_size(row_height, row_height); + const int icon_area_width = icon_area_size.width + icon_hsep; + width += icon_area_width; - int line_from = CLAMP(completion_index - lines / 2, 0, completion_options_size - lines); + const int line_from = CLAMP(completion_index - row_count / 2, 0, completion_options_size - row_count); - for (int i = 0; i < lines; i++) { + for (int i = 0; i < row_count; i++) { int l = line_from + i; ERR_CONTINUE(l < 0 || l >= completion_options_size); if (completion_options[l].default_value.get_type() == Variant::COLOR) { - w += icon_area_size.width; + width += icon_area_size.width; break; } } - int th = h + csb->get_minimum_size().y; + // Position completion panel + completion_rect.size.width = width + 2; + completion_rect.size.height = completion_rows_height; - if (cursor_pos.y + row_height + th > get_size().height) { - completion_rect.position.y = cursor_pos.y - th - (cache.line_spacing / 2.0f) - cursor_insert_offset_y; - } else { - completion_rect.position.y = cursor_pos.y + cache.font->get_height(cache.font_size) + (cache.line_spacing / 2.0f) + csb->get_offset().y - cursor_insert_offset_y; - completion_below = true; + if (completion_options_size <= maxlines) { + scroll_rectangle_width = 0; } - if (cursor_pos.x - nofs + w + scrollw > get_size().width) { - completion_rect.position.x = get_size().width - w - scrollw; + const Point2 csb_offset = csb->get_offset(); + + const int total_width = completion_rect.size.width + csb->get_minimum_size().x + scroll_rectangle_width; + const int total_height = completion_rect.size.height + csb->get_minimum_size().y; + + const int rect_left_border_x = cursor_pos.x - completion_base_width - icon_area_width - csb_offset.x; + const int rect_right_border_x = rect_left_border_x + total_width; + + if (rect_left_border_x < 0) { + // Anchor the completion panel to the left + completion_rect.position.x = 0; + } else if (rect_right_border_x > get_size().width) { + // Anchor the completion panel to the right + completion_rect.position.x = get_size().width - total_width; } else { - completion_rect.position.x = cursor_pos.x - nofs; + // Let the completion panel float with the cursor + completion_rect.position.x = rect_left_border_x; } - completion_rect.size.width = w + 2; - completion_rect.size.height = h; - if (completion_options_size <= maxlines) { - scrollw = 0; + if (cursor_pos.y + row_height + total_height > get_size().height) { + // Completion panel above the cursor line + completion_rect.position.y = cursor_pos.y - total_height; + } else { + // Completion panel below the cursor line + completion_rect.position.y = cursor_pos.y + row_height; + completion_below = true; } - draw_style_box(csb, Rect2(completion_rect.position - csb->get_offset(), completion_rect.size + csb->get_minimum_size() + Size2(scrollw, 0))); + draw_style_box(csb, Rect2(completion_rect.position - csb_offset, completion_rect.size + csb->get_minimum_size() + Size2(scroll_rectangle_width, 0))); if (cache.completion_background_color.a > 0.01) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scrollw, 0)), cache.completion_background_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scroll_rectangle_width, 0)), cache.completion_background_color); } RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.position.x, completion_rect.position.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color); - draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(nofs, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color); + draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(completion_base_width, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color); - for (int i = 0; i < lines; i++) { + for (int i = 0; i < row_count; i++) { int l = line_from + i; ERR_CONTINUE(l < 0 || l >= completion_options_size); @@ -1557,11 +1579,11 @@ void TextEdit::_notification(int p_what) { tl->draw(ci, title_pos, completion_options[l].font_color); } - if (scrollw) { + if (scroll_rectangle_width) { // Draw a small scroll rectangle to show a position in the options. float r = (float)maxlines / completion_options_size; float o = (float)line_from / completion_options_size; - draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc); + draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scroll_rectangle_width, completion_rect.size.y * r), scrollc); } completion_line_ofs = line_from; @@ -1569,7 +1591,7 @@ void TextEdit::_notification(int p_what) { // Check to see if the hint should be drawn. bool show_hint = false; - if (completion_hint != "") { + if (is_cursor_line_visible && completion_hint != "") { if (completion_active) { if (completion_below && !callhint_below) { show_hint = true; @@ -2274,7 +2296,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { int prev_col = cursor.column; int prev_line = cursor.line; - cursor_set_line(row, true, false); + cursor_set_line(row, false, false); cursor_set_column(col); if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) { @@ -6106,7 +6128,7 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const { } // Count the number of visible lines up to this line. - double new_line_scroll_pos = 0; + double new_line_scroll_pos = 0.0; int to = CLAMP(p_line, 0, text.size() - 1); for (int i = 0; i < to; i++) { if (!text.is_hidden(i)) { @@ -6884,7 +6906,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) { update(); } } - _change_notify(); + notify_property_list_changed(); return true; } @@ -7183,23 +7205,11 @@ void TextEdit::_bind_methods() { } TextEdit::TextEdit() { - setting_row = false; - draw_tabs = false; - draw_spaces = false; - override_selected_font_color = false; - draw_caret = true; - max_chars = 0; clear(); - wrap_enabled = false; - wrap_at = 0; - wrap_right_offset = 10; set_focus_mode(FOCUS_ALL); _update_caches(); - cache.line_spacing = 1; - cache.font_size = 16; set_default_cursor_shape(CURSOR_IBEAM); - indent_size = 4; text.set_indent_size(indent_size); text.clear(); @@ -7209,31 +7219,16 @@ TextEdit::TextEdit() { add_child(h_scroll); add_child(v_scroll); - updating_scrolls = false; - selection.active = false; - h_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved)); v_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved)); v_scroll->connect("scrolling", callable_mp(this, &TextEdit::_v_scroll_input)); - cursor_changed_dirty = false; - text_changed_dirty = false; - - selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE; - selection.selecting_line = 0; - selection.selecting_column = 0; - selection.selecting_text = false; - selection.active = false; - - block_caret = false; - caret_blink_enabled = false; caret_blink_timer = memnew(Timer); add_child(caret_blink_timer); caret_blink_timer->set_wait_time(0.65); caret_blink_timer->connect("timeout", callable_mp(this, &TextEdit::_toggle_draw_caret)); cursor_set_blink_enabled(false); - right_click_moves_caret = true; idle_detect = memnew(Timer); add_child(idle_detect); @@ -7246,54 +7241,8 @@ TextEdit::TextEdit() { click_select_held->set_wait_time(0.05); click_select_held->connect("timeout", callable_mp(this, &TextEdit::_click_selection_held)); - current_op.type = TextOperation::TYPE_NONE; - undo_enabled = true; undo_stack_max_size = GLOBAL_GET("gui/common/text_edit_undo_stack_max_size"); - undo_stack_pos = nullptr; - setting_text = false; - last_dblclk = 0; - current_op.version = 0; - version = 0; - saved_version = 0; - completion_enabled = false; - completion_active = false; - completion_line_ofs = 0; - tooltip_obj = nullptr; - line_length_guidelines = false; - line_length_guideline_soft_col = 80; - line_length_guideline_hard_col = 100; - hiding_enabled = false; - next_operation_is_complex = false; - scroll_past_end_of_file_enabled = false; - auto_brace_completion_enabled = false; - brace_matching_enabled = false; - highlight_all_occurrences = false; - highlight_current_line = false; - indent_using_spaces = false; - space_indent = " "; - auto_indent = false; - insert_mode = false; - window_has_focus = true; - select_identifiers_enabled = false; - smooth_scroll_enabled = false; - scrolling = false; - minimap_clicked = false; - dragging_minimap = false; - can_drag_minimap = false; - minimap_scroll_ratio = 0; - minimap_scroll_click_pos = 0; - dragging_selection = false; - target_v_scroll = 0; - v_scroll_speed = 80; - draw_minimap = false; - minimap_width = 80; - minimap_char_size = Point2(1, 2); - minimap_line_spacing = 1; - - selecting_enabled = true; - context_menu_enabled = true; - shortcut_keys_enabled = true; menu = memnew(PopupMenu); add_child(menu); @@ -7328,12 +7277,10 @@ TextEdit::TextEdit() { menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY); menu->add_child(menu_ctl); - readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly. set_readonly(false); menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); menu_dir->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); menu_ctl->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); - first_draw = true; } TextEdit::~TextEdit() { diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index dc811059c8..37299ec063 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -92,14 +92,11 @@ private: Vector<Vector2i> bidi_override; Ref<TextParagraph> data_buf; - bool marked; - bool hidden; + bool marked = false; + bool hidden = false; Line() { data_buf.instance(); - - marked = false; - hidden = false; } }; @@ -173,46 +170,31 @@ private: }; struct Cursor { - int last_fit_x; - int line, column; ///< cursor - int x_ofs, line_ofs, wrap_ofs; - Cursor() { - last_fit_x = 0; - line = 0; - column = 0; ///< cursor - x_ofs = 0; - line_ofs = 0; - wrap_ofs = 0; - } + int last_fit_x = 0; + int line = 0; + int column = 0; ///< cursor + int x_ofs = 0; + int line_ofs = 0; + int wrap_ofs = 0; } cursor; struct Selection { - SelectionMode selecting_mode; - int selecting_line, selecting_column; - int selected_word_beg, selected_word_end, selected_word_origin; - bool selecting_text; - - bool active; - - int from_line, from_column; - int to_line, to_column; - - bool shiftclick_left; - Selection() { - selecting_mode = SelectionMode::SELECTION_MODE_NONE; - selecting_line = 0; - selecting_column = 0; - selected_word_beg = 0; - selected_word_end = 0; - selected_word_origin = 0; - selecting_text = false; - active = false; - from_line = 0; - from_column = 0; - to_line = 0; - to_column = 0; - shiftclick_left = false; - } + SelectionMode selecting_mode = SelectionMode::SELECTION_MODE_NONE; + int selecting_line = 0; + int selecting_column = 0; + int selected_word_beg = 0; + int selected_word_end = 0; + int selected_word_origin = 0; + bool selecting_text = false; + + bool active = false; + + int from_line = 0; + int from_column = 0; + int to_line = 0; + int to_column = 0; + + bool shiftclick_left = false; } selection; Map<int, Dictionary> syntax_highlighting_cache; @@ -224,25 +206,16 @@ private: TYPE_REMOVE }; - Type type; - int from_line, from_column; - int to_line, to_column; + Type type = TYPE_NONE; + int from_line = 0; + int from_column = 0; + int to_line = 0; + int to_column = 0; String text; - uint32_t prev_version; - uint32_t version; - bool chain_forward; - bool chain_backward; - TextOperation() { - type = TYPE_NONE; - from_line = 0; - from_column = 0; - to_line = 0; - to_column = 0; - prev_version = 0; - version = 0; - chain_forward = false; - chain_backward = false; - } + uint32_t prev_version = 0; + uint32_t version = 0; + bool chain_forward = false; + bool chain_backward = false; }; String ime_text; @@ -251,7 +224,7 @@ private: TextOperation current_op; List<TextOperation> undo_stack; - List<TextOperation>::Element *undo_stack_pos; + List<TextOperation>::Element *undo_stack_pos = nullptr; int undo_stack_max_size; void _clear_redo(); @@ -264,20 +237,20 @@ private: Dictionary _get_line_syntax_highlighting(int p_line); Set<String> completion_prefixes; - bool completion_enabled; + bool completion_enabled = false; List<ScriptCodeCompletionOption> completion_sources; Vector<ScriptCodeCompletionOption> completion_options; - bool completion_active; - bool completion_forced; + bool completion_active = false; + bool completion_forced = false; ScriptCodeCompletionOption completion_current; String completion_base; - int completion_index; + int completion_index = 0; Rect2i completion_rect; - int completion_line_ofs; + int completion_line_ofs = 0; String completion_hint; - int completion_hint_offset; + int completion_hint_offset = 0; - bool setting_text; + bool setting_text = false; // data Text text; @@ -290,93 +263,93 @@ private: Array st_args; bool draw_control_chars = false; - uint32_t version; - uint32_t saved_version; + uint32_t version = 0; + uint32_t saved_version = 0; - int max_chars; - bool readonly; - bool indent_using_spaces; - int indent_size; - String space_indent; + int max_chars = 0; + bool readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly. + bool indent_using_spaces = false; + int indent_size = 4; + String space_indent = " "; Timer *caret_blink_timer; - bool caret_blink_enabled; - bool draw_caret; - bool window_has_focus; - bool block_caret; - bool right_click_moves_caret; + bool caret_blink_enabled = false; + bool draw_caret = true; + bool window_has_focus = true; + bool block_caret = false; + bool right_click_moves_caret = true; bool mid_grapheme_caret_enabled = false; - bool wrap_enabled; - int wrap_at; - int wrap_right_offset; - - bool first_draw; - bool setting_row; - bool draw_tabs; - bool draw_spaces; - bool override_selected_font_color; - bool cursor_changed_dirty; - bool text_changed_dirty; - bool undo_enabled; - bool line_length_guidelines; - int line_length_guideline_soft_col; - int line_length_guideline_hard_col; - bool hiding_enabled; - bool draw_minimap; - int minimap_width; - Point2 minimap_char_size; - int minimap_line_spacing; - - bool highlight_all_occurrences; - bool scroll_past_end_of_file_enabled; - bool auto_brace_completion_enabled; - bool brace_matching_enabled; - bool highlight_current_line; - bool auto_indent; + bool wrap_enabled = false; + int wrap_at = 0; + int wrap_right_offset = 10; + + bool first_draw = true; + bool setting_row = false; + bool draw_tabs = false; + bool draw_spaces = false; + bool override_selected_font_color = false; + bool cursor_changed_dirty = false; + bool text_changed_dirty = false; + bool undo_enabled = true; + bool line_length_guidelines = false; + int line_length_guideline_soft_col = 80; + int line_length_guideline_hard_col = 100; + bool hiding_enabled = false; + bool draw_minimap = false; + int minimap_width = 80; + Point2 minimap_char_size = Point2(1, 2); + int minimap_line_spacing = 1; + + bool highlight_all_occurrences = false; + bool scroll_past_end_of_file_enabled = false; + bool auto_brace_completion_enabled = false; + bool brace_matching_enabled = false; + bool highlight_current_line = false; + bool auto_indent = false; String cut_copy_line; - bool insert_mode; - bool select_identifiers_enabled; - - bool smooth_scroll_enabled; - bool scrolling; - bool dragging_selection; - bool dragging_minimap; - bool can_drag_minimap; - bool minimap_clicked; - double minimap_scroll_ratio; - double minimap_scroll_click_pos; - float target_v_scroll; - float v_scroll_speed; + bool insert_mode = false; + bool select_identifiers_enabled = false; + + bool smooth_scroll_enabled = false; + bool scrolling = false; + bool dragging_selection = false; + bool dragging_minimap = false; + bool can_drag_minimap = false; + bool minimap_clicked = false; + double minimap_scroll_ratio = 0.0; + double minimap_scroll_click_pos = 0.0; + float target_v_scroll = 0.0; + float v_scroll_speed = 80.0; String highlighted_word; - uint64_t last_dblclk; + uint64_t last_dblclk = 0; Timer *idle_detect; Timer *click_select_held; HScrollBar *h_scroll; VScrollBar *v_scroll; - bool updating_scrolls; + bool updating_scrolls = false; - Object *tooltip_obj; + Object *tooltip_obj = nullptr; StringName tooltip_func; Variant tooltip_ud; - bool next_operation_is_complex; + bool next_operation_is_complex = false; - bool callhint_below; + bool callhint_below = false; Vector2 callhint_offset; String search_text; - uint32_t search_flags; - int search_result_line; - int search_result_col; + uint32_t search_flags = 0; + int search_result_line = 0; + int search_result_col = 0; - bool selecting_enabled; + bool selecting_enabled = true; - bool context_menu_enabled; - bool shortcut_keys_enabled; + bool context_menu_enabled = true; + bool shortcut_keys_enabled = true; bool virtual_keyboard_enabled = true; void _generate_context_menu(); @@ -477,7 +450,7 @@ protected: Ref<StyleBox> style_focus; Ref<StyleBox> style_readonly; Ref<Font> font; - int font_size; + int font_size = 16; Color completion_background_color; Color completion_selected_color; Color completion_existing_color; @@ -498,12 +471,8 @@ protected: Color search_result_border_color; Color background_color; - int line_spacing; - int minimap_width; - Cache() { - line_spacing = 0; - minimap_width = 0; - } + int line_spacing = 1; + int minimap_width = 0; } cache; virtual String get_tooltip(const Point2 &p_pos) const override; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 23c48b0906..f43e3d1a9d 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -29,7 +29,9 @@ /*************************************************************************/ #include "texture_button.h" + #include "core/typedefs.h" + #include <stdlib.h> Size2 TextureButton::get_minimum_size() const { @@ -247,8 +249,8 @@ void TextureButton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_disabled_texture", "texture"), &TextureButton::set_disabled_texture); ClassDB::bind_method(D_METHOD("set_focused_texture", "texture"), &TextureButton::set_focused_texture); ClassDB::bind_method(D_METHOD("set_click_mask", "mask"), &TextureButton::set_click_mask); - ClassDB::bind_method(D_METHOD("set_expand", "p_expand"), &TextureButton::set_expand); - ClassDB::bind_method(D_METHOD("set_stretch_mode", "p_mode"), &TextureButton::set_stretch_mode); + ClassDB::bind_method(D_METHOD("set_expand", "expand"), &TextureButton::set_expand); + ClassDB::bind_method(D_METHOD("set_stretch_mode", "mode"), &TextureButton::set_stretch_mode); ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureButton::set_flip_h); ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureButton::is_flipped_h); ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureButton::set_flip_v); @@ -375,13 +377,4 @@ bool TextureButton::is_flipped_v() const { return vflip; } -TextureButton::TextureButton() { - expand = false; - stretch_mode = STRETCH_SCALE; - hflip = false; - vflip = false; - - _texture_region = Rect2(); - _position_rect = Rect2(); - _tile = false; -} +TextureButton::TextureButton() {} diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 4b750c3fb1..8361f3c341 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -54,15 +54,15 @@ private: Ref<Texture2D> disabled; Ref<Texture2D> focused; Ref<BitMap> click_mask; - bool expand; - StretchMode stretch_mode; + bool expand = false; + StretchMode stretch_mode = STRETCH_SCALE; Rect2 _texture_region; Rect2 _position_rect; - bool _tile; + bool _tile = false; - bool hflip; - bool vflip; + bool hflip = false; + bool vflip = false; protected: virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp index 76564e2b17..46ce9d5ca9 100644 --- a/scene/gui/texture_progress_bar.cpp +++ b/scene/gui/texture_progress_bar.cpp @@ -145,9 +145,9 @@ Point2 TextureProgressBar::unit_val_to_uv(float val) { float angle = (val * Math_TAU) - Math_PI * 0.5; Point2 dir = Vector2(Math::cos(angle), Math::sin(angle)); float t1 = 1.0; - float cp = 0; - float cq = 0; - float cr = 0; + float cp = 0.0; + float cq = 0.0; + float cr = 0.0; float edgeLeft = 0.0; float edgeRight = 1.0; float edgeBottom = 0.0; @@ -540,17 +540,5 @@ void TextureProgressBar::_bind_methods() { } TextureProgressBar::TextureProgressBar() { - mode = FILL_LEFT_TO_RIGHT; - rad_init_angle = 0; - rad_center_off = Point2(); - rad_max_degrees = 360; set_mouse_filter(MOUSE_FILTER_PASS); - - nine_patch_stretch = false; - stretch_margin[SIDE_LEFT] = 0; - stretch_margin[SIDE_RIGHT] = 0; - stretch_margin[SIDE_BOTTOM] = 0; - stretch_margin[SIDE_TOP] = 0; - - tint_under = tint_progress = tint_over = Color(1, 1, 1); } diff --git a/scene/gui/texture_progress_bar.h b/scene/gui/texture_progress_bar.h index ee33a915f7..a3883a7017 100644 --- a/scene/gui/texture_progress_bar.h +++ b/scene/gui/texture_progress_bar.h @@ -98,13 +98,15 @@ public: TextureProgressBar(); private: - FillMode mode; - float rad_init_angle; - float rad_max_degrees; + FillMode mode = FILL_LEFT_TO_RIGHT; + float rad_init_angle = 0.0; + float rad_max_degrees = 360.0; Point2 rad_center_off; - bool nine_patch_stretch; - int stretch_margin[4]; - Color tint_under, tint_progress, tint_over; + bool nine_patch_stretch = false; + int stretch_margin[4] = {}; + Color tint_under = Color(1, 1, 1); + Color tint_progress = Color(1, 1, 1); + Color tint_over = Color(1, 1, 1); Point2 unit_val_to_uv(float val); Point2 get_relative_center(); diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index beb06b7739..1cba88e06f 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -217,11 +217,7 @@ bool TextureRect::is_flipped_v() const { } TextureRect::TextureRect() { - expand = false; - hflip = false; - vflip = false; set_mouse_filter(MOUSE_FILTER_PASS); - stretch_mode = STRETCH_SCALE_ON_EXPAND; } TextureRect::~TextureRect() { diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index 0f3172f5bd..0f93d5732f 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -49,11 +49,11 @@ public: }; private: - bool expand; - bool hflip; - bool vflip; + bool expand = false; + bool hflip = false; + bool vflip = false; Ref<Texture2D> texture; - StretchMode stretch_mode; + StretchMode stretch_mode = STRETCH_SCALE_ON_EXPAND; void _texture_changed(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 0049b54f50..e8e3aeea68 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3322,6 +3322,14 @@ void Tree::item_selected(int p_column, TreeItem *p_item) { } void Tree::item_deselected(int p_column, TreeItem *p_item) { + if (selected_item == p_item) { + selected_item = nullptr; + } + + if (selected_col == p_column) { + selected_col = -1; + } + if (select_mode == SELECT_MULTI || select_mode == SELECT_SINGLE) { p_item->cells.write[p_column].selected = false; } @@ -4174,6 +4182,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language); ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll); + ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::_scroll_to_item); ClassDB::bind_method(D_METHOD("set_hide_folding", "hide"), &Tree::set_hide_folding); ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden); @@ -4223,19 +4232,8 @@ void Tree::_bind_methods() { } Tree::Tree() { - selected_col = 0; columns.resize(1); - selected_item = nullptr; - edited_item = nullptr; - selected_col = -1; - edited_col = -1; - hide_root = false; - select_mode = SELECT_SINGLE; - root = nullptr; - popup_menu = nullptr; - popup_edited_item = nullptr; - text_editor = nullptr; set_focus_mode(FOCUS_ALL); popup_menu = memnew(PopupMenu); @@ -4279,50 +4277,9 @@ Tree::Tree() { set_notify_transform(true); - updating_value_editor = false; - pressed_button = -1; - show_column_titles = false; - - cache.click_type = Cache::CLICK_NONE; - cache.hover_type = Cache::CLICK_NONE; - cache.hover_index = -1; - cache.click_index = -1; - cache.click_id = -1; - cache.click_item = nullptr; - cache.click_column = 0; - cache.hover_cell = -1; - last_keypress = 0; - focus_in_id = 0; - - blocked = 0; - - cursor_can_exit_tree = true; set_mouse_filter(MOUSE_FILTER_STOP); - drag_speed = 0; - drag_touching = false; - drag_touching_deaccel = false; - pressing_for_editor = false; - range_drag_enabled = false; - - hide_folding = false; - - drop_mode_flags = 0; - drop_mode_over = nullptr; - drop_mode_section = 0; - single_select_defer = nullptr; - - scrolling = false; - allow_rmb_select = false; - force_edit_checkbox_only_on_checkbox = false; - set_clip_contents(true); - - cache.hover_item = nullptr; - cache.hover_cell = -1; - - allow_reselect = false; - propagate_mouse_activated = false; } Tree::~Tree() { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 2136bada0b..c3c8052b67 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -62,7 +62,7 @@ private: friend class Tree; struct Cell { - TreeCellMode mode; + TreeCellMode mode = TreeItem::CELL_MODE_STRING; Ref<Texture2D> icon; Rect2i icon_region; @@ -74,24 +74,27 @@ private: Control::StructuredTextParser st_parser = Control::STRUCTURED_TEXT_DEFAULT; Array st_args; Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED; - bool dirty; - double min, max, step, val; - int icon_max_w; - bool expr; - bool checked; - bool editable; - bool selected; - bool selectable; - bool custom_color; + bool dirty = true; + double min = 0.0; + double max = 100.0; + double step = 1.0; + double val = 0.0; + int icon_max_w = 0; + bool expr = false; + bool checked = false; + bool editable = false; + bool selected = false; + bool selectable = true; + bool custom_color = false; Color color; - bool custom_bg_color; - bool custom_bg_outline; + bool custom_bg_color = false; + bool custom_bg_outline = false; Color bg_color; - bool custom_button; - bool expand_right; - Color icon_color; + bool custom_button = false; + bool expand_right = false; + Color icon_color = Color(1, 1, 1); - TextAlign text_align; + TextAlign text_align = ALIGN_LEFT; Variant meta; String tooltip; @@ -100,42 +103,17 @@ private: StringName custom_draw_callback; struct Button { - int id; - bool disabled; + int id = 0; + bool disabled = false; Ref<Texture2D> texture; - Color color; + Color color = Color(1, 1, 1, 1); String tooltip; - Button() { - id = 0; - disabled = false; - color = Color(1, 1, 1, 1); - tooltip = ""; - } }; Vector<Button> buttons; Cell() { text_buf.instance(); - dirty = true; - custom_draw_obj = ObjectID(); - custom_button = false; - mode = TreeItem::CELL_MODE_STRING; - min = 0; - max = 100; - step = 1; - val = 0; - checked = false; - editable = false; - selected = false; - selectable = true; - custom_color = false; - custom_bg_color = false; - expr = false; - icon_max_w = 0; - text_align = ALIGN_LEFT; - expand_right = false; - icon_color = Color(1, 1, 1); } Size2 get_icon_size() const; @@ -332,46 +310,46 @@ public: private: friend class TreeItem; - TreeItem *root; - TreeItem *popup_edited_item; - TreeItem *selected_item; - TreeItem *edited_item; + TreeItem *root = nullptr; + TreeItem *popup_edited_item = nullptr; + TreeItem *selected_item = nullptr; + TreeItem *edited_item = nullptr; - TreeItem *drop_mode_over; - int drop_mode_section; + TreeItem *drop_mode_over = nullptr; + int drop_mode_section = 0; - TreeItem *single_select_defer; - int single_select_defer_column; + TreeItem *single_select_defer = nullptr; + int single_select_defer_column = 0; - int pressed_button; - bool pressing_for_editor; + int pressed_button = -1; + bool pressing_for_editor = false; String pressing_for_editor_text; Vector2 pressing_pos; Rect2 pressing_item_rect; - float range_drag_base; - bool range_drag_enabled; + float range_drag_base = 0.0; + bool range_drag_enabled = false; Vector2 range_drag_capture_pos; - bool propagate_mouse_activated; + bool propagate_mouse_activated = false; //TreeItem *cursor_item; //int cursor_column; Rect2 custom_popup_rect; - int edited_col; - int selected_col; - int popup_edited_item_col; - bool hide_root; - SelectMode select_mode; + int edited_col = -1; + int selected_col = -1; + int popup_edited_item_col = -1; + bool hide_root = false; + SelectMode select_mode = SELECT_SINGLE; - int blocked; + int blocked = 0; - int drop_mode_flags; + int drop_mode_flags = 0; struct ColumnInfo { - int min_width; - bool expand; + int min_width = 1; + bool expand = true; String title; Ref<TextLine> text_buf; Dictionary opentype_features; @@ -379,27 +357,25 @@ private: Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED; ColumnInfo() { text_buf.instance(); - min_width = 1; - expand = true; } }; - bool show_column_titles; + bool show_column_titles = false; VBoxContainer *popup_editor_vb; Popup *popup_editor; - LineEdit *text_editor; + LineEdit *text_editor = nullptr; HSlider *value_editor; - bool updating_value_editor; - uint64_t focus_in_id; - PopupMenu *popup_menu; + bool updating_value_editor = false; + uint64_t focus_in_id = 0; + PopupMenu *popup_menu = nullptr; Vector<ColumnInfo> columns; Timer *range_click_timer; - TreeItem *range_item_last; - bool range_up_last; + TreeItem *range_item_last = nullptr; + bool range_up_last = false; void _range_click_timeout(); int compute_item_height(TreeItem *p_item) const; @@ -434,8 +410,8 @@ private: struct Cache { Ref<Font> font; Ref<Font> tb_font; - int font_size; - int tb_font_size; + int font_size = 0; + int tb_font_size = 0; Ref<StyleBox> bg; Ref<StyleBox> selected; Ref<StyleBox> selected_focus; @@ -465,15 +441,15 @@ private: Color relationship_line_color; Color custom_button_font_highlight; - int hseparation; - int vseparation; - int item_margin; - int button_margin; + int hseparation = 0; + int vseparation = 0; + int item_margin = 0; + int button_margin = 0; Point2 offset; - int draw_relationship_lines; - int draw_guides; - int scroll_border; - int scroll_speed; + int draw_relationship_lines = 0; + int draw_guides = 0; + int scroll_border = 0; + int scroll_speed = 0; enum ClickType { CLICK_NONE, @@ -482,17 +458,17 @@ private: }; - ClickType click_type; - ClickType hover_type; - int click_index; - int click_id; - TreeItem *click_item; - int click_column; - int hover_index; + ClickType click_type = Cache::CLICK_NONE; + ClickType hover_type = Cache::CLICK_NONE; + int click_index = -1; + int click_id = -1; + TreeItem *click_item = nullptr; + int click_column = 0; + int hover_index = -1; Point2 click_pos; - TreeItem *hover_item; - int hover_cell; + TreeItem *hover_item = nullptr; + int hover_cell = -1; Point2i text_editor_position; @@ -510,9 +486,9 @@ private: Rect2 search_item_rect(TreeItem *p_from, TreeItem *p_item); //Rect2 get_item_rect(TreeItem *p_item); - uint64_t last_keypress; + uint64_t last_keypress = 0; String incr_search; - bool cursor_can_exit_tree; + bool cursor_can_exit_tree = true; void _do_incr_search(const String &p_add); TreeItem *_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards = false); @@ -526,21 +502,21 @@ private: float last_drag_time; float time_since_motion;*/ - float drag_speed; - float drag_from; - float drag_accum; + float drag_speed = 0.0; + float drag_from = 0.0; + float drag_accum = 0.0; Vector2 last_speed; - bool drag_touching; - bool drag_touching_deaccel; - bool click_handled; - bool allow_rmb_select; - bool scrolling; + bool drag_touching = false; + bool drag_touching_deaccel = false; + bool click_handled = false; + bool allow_rmb_select = false; + bool scrolling = false; - bool allow_reselect; + bool allow_reselect = false; - bool force_edit_checkbox_only_on_checkbox; + bool force_edit_checkbox_only_on_checkbox = false; - bool hide_folding; + bool hide_folding = false; int _count_selected_items(TreeItem *p_from) const; void _go_left(); @@ -564,6 +540,10 @@ protected: return get_item_rect(Object::cast_to<TreeItem>(p_item), p_column); } + void _scroll_to_item(Object *p_item) { + scroll_to_item(Object::cast_to<TreeItem>(p_item)); + } + public: virtual String get_tooltip(const Point2 &p_pos) const override; diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 84d689369b..0590ae2415 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -462,25 +462,7 @@ void VideoPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); } -VideoPlayer::VideoPlayer() { - volume = 1; - loops = false; - paused = false; - autoplay = false; - expand = true; - - audio_track = 0; - bus_index = 0; - - buffering_ms = 500; - - // internal_stream.player=this; - // stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream); - last_audio_time = 0; - - wait_resampler = 0; - wait_resampler_limit = 2; -}; +VideoPlayer::VideoPlayer() {} VideoPlayer::~VideoPlayer() { // if (stream_rid.is_valid()) diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h index 089337eed5..0edad296a1 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_player.h @@ -41,8 +41,8 @@ class VideoPlayer : public Control { struct Output { AudioFrame vol; - int bus_index; - Viewport *viewport; //pointer only used for reference to previous mix + int bus_index = 0; + Viewport *viewport = nullptr; //pointer only used for reference to previous mix }; Ref<VideoStreamPlayback> playback; Ref<VideoStream> stream; @@ -56,17 +56,18 @@ class VideoPlayer : public Control { AudioRBResampler resampler; Vector<AudioFrame> mix_buffer; - int wait_resampler, wait_resampler_limit; - - bool paused; - bool autoplay; - float volume; - double last_audio_time; - bool expand; - bool loops; - int buffering_ms; - int audio_track; - int bus_index; + int wait_resampler = 0; + int wait_resampler_limit = 2; + + bool paused = false; + bool autoplay = false; + float volume = 1.0; + double last_audio_time = 0.0; + bool expand = true; + bool loops = false; + int buffering_ms = 500; + int audio_track = 0; + int bus_index = 0; StringName bus; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index efef49fbf0..90bc99a941 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -203,7 +203,7 @@ CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const { void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) { particles_animation = p_particles_anim; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool CanvasItemMaterial::get_particles_animation() const { @@ -387,7 +387,6 @@ void CanvasItem::show() { } _propagate_visibility_changed(true); - _change_notify("visible"); } void CanvasItem::hide() { @@ -403,7 +402,6 @@ void CanvasItem::hide() { } _propagate_visibility_changed(false); - _change_notify("visible"); } CanvasItem *CanvasItem::current_item_drawn = nullptr; @@ -1035,7 +1033,7 @@ void CanvasItem::set_material(const Ref<Material> &p_material) { rid = material->get_rid(); } RS::get_singleton()->canvas_item_set_material(canvas_item, rid); - _change_notify(); //properties for material exposed + notify_property_list_changed(); //properties for material exposed } void CanvasItem::set_use_parent_material(bool p_use_parent_material) { @@ -1341,7 +1339,7 @@ void CanvasItem::set_texture_filter(TextureFilter p_texture_filter) { } texture_filter = p_texture_filter; _update_texture_filter_changed(true); - _change_notify(); + notify_property_list_changed(); } CanvasItem::TextureFilter CanvasItem::get_texture_filter() const { @@ -1381,7 +1379,7 @@ void CanvasItem::set_texture_repeat(TextureRepeat p_texture_repeat) { } texture_repeat = p_texture_repeat; _update_texture_repeat_changed(true); - _change_notify(); + notify_property_list_changed(); } void CanvasItem::set_clip_children(bool p_enabled) { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 64eb3f4e0a..e22f93a7ea 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -90,7 +90,7 @@ private: struct ShaderData { RID shader; - int users; + int users = 0; }; static Map<MaterialKey, ShaderData> shader_map; diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 9826d9d4db..91daa08ff8 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -303,17 +303,7 @@ void CanvasLayer::_bind_methods() { } CanvasLayer::CanvasLayer() { - vp = nullptr; - scale = Vector2(1, 1); - rot = 0; - locrotscale_dirty = false; - layer = 1; canvas = RS::get_singleton()->canvas_create(); - custom_viewport = nullptr; - - sort_index = 0; - follow_viewport = false; - follow_viewport_scale = 1.0; } CanvasLayer::~CanvasLayer() { diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index cb10c6299b..181d1dd659 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -38,24 +38,24 @@ class Viewport; class CanvasLayer : public Node { GDCLASS(CanvasLayer, Node); - bool locrotscale_dirty; + bool locrotscale_dirty = false; Vector2 ofs; - Size2 scale; - real_t rot; - int layer; + Size2 scale = Vector2(1, 1); + real_t rot = 0.0; + int layer = 1; Transform2D transform; RID canvas; ObjectID custom_viewport_id; // to check validity - Viewport *custom_viewport; + Viewport *custom_viewport = nullptr; RID viewport; - Viewport *vp; + Viewport *vp = nullptr; - int sort_index; + int sort_index = 0; - bool follow_viewport; - float follow_viewport_scale; + bool follow_viewport = false; + float follow_viewport_scale = 1.0; void _update_xform(); void _update_locrotscale(); diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 4c6b85d78b..384e7d2652 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -638,29 +638,11 @@ void HTTPRequest::_bind_methods() { } HTTPRequest::HTTPRequest() { - port = 80; - redirections = 0; - max_redirects = 8; - body_len = -1; - got_response = false; - validate_ssl = false; - use_ssl = false; - accept_gzip = true; - response_code = 0; - request_sent = false; - requesting = false; client.instance(); - use_threads = false; - thread_done = false; - downloaded = 0; - body_size_limit = -1; - file = nullptr; - timer = memnew(Timer); timer->set_one_shot(true); timer->connect("timeout", callable_mp(this, &HTTPRequest::_timeout)); add_child(timer); - timeout = 0; } HTTPRequest::~HTTPRequest() { diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 9dbf561cd4..5525ea7912 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -60,42 +60,42 @@ public: }; private: - bool requesting; + bool requesting = false; String request_string; String url; - int port; + int port = 80; Vector<String> headers; - bool validate_ssl; - bool use_ssl; + bool validate_ssl = false; + bool use_ssl = false; HTTPClient::Method method; Vector<uint8_t> request_data; - bool request_sent; + bool request_sent = false; Ref<HTTPClient> client; PackedByteArray body; - volatile bool use_threads; - bool accept_gzip; + volatile bool use_threads = false; + bool accept_gzip = true; - bool got_response; - int response_code; + bool got_response = false; + int response_code = 0; Vector<String> response_headers; String download_to_file; - FileAccess *file; + FileAccess *file = nullptr; - int body_len; - volatile int downloaded; - int body_size_limit; + int body_len = -1; + volatile int downloaded = 0; + int body_size_limit = -1; - int redirections; + int redirections = 0; bool _update_connection(); - int max_redirects; + int max_redirects = 8; - int timeout; + int timeout = 0; void _redirect_request(const String &p_new_url); @@ -107,8 +107,8 @@ private: bool has_header(const PackedStringArray &p_headers, const String &p_header_name); String get_header_value(const PackedStringArray &p_headers, const String &header_name); - volatile bool thread_done; - volatile bool thread_request_quit; + volatile bool thread_done = false; + volatile bool thread_request_quit = false; Thread thread; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 6a1b896b04..9ac3b4a691 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -367,8 +367,6 @@ void Node::set_physics_process(bool p_process) { } else { remove_from_group("physics_process"); } - - _change_notify("physics_process"); } bool Node::is_physics_processing() const { @@ -387,8 +385,6 @@ void Node::set_physics_process_internal(bool p_process_internal) { } else { remove_from_group("physics_process_internal"); } - - _change_notify("physics_process_internal"); } bool Node::is_physics_processing_internal() const { @@ -466,7 +462,7 @@ uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_ nd.name = p_method; nd.mode = p_mode; data.rpc_methods.push_back(nd); - return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); + return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); } else { int c_mid = (~(1 << 15)) & mid; data.rpc_methods.write[c_mid].mode = p_mode; @@ -555,7 +551,7 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { + if (p_args[0]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -584,7 +580,7 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal return Variant(); } - if (p_args[1]->get_type() != Variant::STRING) { + if (p_args[1]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -607,7 +603,7 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Calla return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { + if (p_args[0]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; @@ -636,7 +632,7 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Ca return Variant(); } - if (p_args[1]->get_type() != Variant::STRING) { + if (p_args[1]->get_type() != Variant::STRING_NAME) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; @@ -863,8 +859,6 @@ void Node::set_process(bool p_process) { } else { remove_from_group("process"); } - - _change_notify("process"); } bool Node::is_processing() const { @@ -883,8 +877,6 @@ void Node::set_process_internal(bool p_process_internal) { } else { remove_from_group("process_internal"); } - - _change_notify("process_internal"); } bool Node::is_processing_internal() const { @@ -2332,12 +2324,7 @@ static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) { } } -struct _NodeReplaceByPair { - String name; - Variant value; -}; - -void Node::replace_by(Node *p_node, bool p_keep_data) { +void Node::replace_by(Node *p_node, bool p_keep_groups) { ERR_FAIL_NULL(p_node); ERR_FAIL_COND(p_node->data.parent); @@ -2345,21 +2332,7 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { List<Node *> owned_by_owner; Node *owner = (data.owner == this) ? p_node : data.owner; - List<_NodeReplaceByPair> replace_data; - - if (p_keep_data) { - List<PropertyInfo> plist; - get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - _NodeReplaceByPair rd; - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - rd.name = E->get().name; - rd.value = get(rd.name); - } - + if (p_keep_groups) { List<GroupInfo> groups; get_groups(&groups); @@ -2404,10 +2377,6 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { } p_node->set_filename(get_filename()); - - for (List<_NodeReplaceByPair>::Element *E = replace_data.front(); E; E = E->next()) { - p_node->set(E->get().name, E->get().value); - } } void Node::_replace_connections_target(Node *p_new_target) { @@ -2774,7 +2743,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree); ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANCING | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS)); - ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_data"), &Node::replace_by, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder); ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder); diff --git a/scene/main/node.h b/scene/main/node.h index a0dca75791..5253ed2e45 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -80,7 +80,7 @@ private: struct NetData { StringName name; - MultiplayerAPI::RPCMode mode; + MultiplayerAPI::RPCMode mode = MultiplayerAPI::RPCMode::RPC_MODE_DISABLED; }; struct Data { @@ -297,7 +297,7 @@ public: struct GroupInfo { StringName name; - bool persistent; + bool persistent = false; }; void get_groups(List<GroupInfo> *p_groups) const; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 1c9d81e87c..0161786681 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -90,10 +90,7 @@ void SceneTreeTimer::release_connections() { } } -SceneTreeTimer::SceneTreeTimer() { - time_left = 0; - process_pause = true; -} +SceneTreeTimer::SceneTreeTimer() {} void SceneTree::tree_changed() { tree_version++; @@ -409,6 +406,7 @@ bool SceneTree::physics_process(float p_time) { emit_signal("physics_frame"); _notify_group_pause("physics_process_internal", Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS); + call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_process_picking"); _notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS); _flush_ugc(); MessageQueue::get_singleton()->flush(); //small little hack diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 748908c8a6..35622c2031 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -51,8 +51,8 @@ class SceneDebugger; class SceneTreeTimer : public Reference { GDCLASS(SceneTreeTimer, Reference); - float time_left; - bool process_pause; + float time_left = 0.0; + bool process_pause = true; protected: static void _bind_methods(); @@ -80,8 +80,7 @@ public: private: struct Group { Vector<Node *> nodes; - bool changed; - Group() { changed = false; }; + bool changed = false; }; Window *root = nullptr; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 4485cffff5..b6b2982155 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -277,6 +277,4 @@ void ShaderGlobalsOverride::_bind_methods() { ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate); } -ShaderGlobalsOverride::ShaderGlobalsOverride() { - active = false; -} +ShaderGlobalsOverride::ShaderGlobalsOverride() {} diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h index 9e666a0ec5..8d8794d465 100644 --- a/scene/main/shader_globals_override.h +++ b/scene/main/shader_globals_override.h @@ -43,7 +43,7 @@ class ShaderGlobalsOverride : public Node { StringName *_remap(const StringName &p_name) const; - bool active; + bool active = false; mutable HashMap<StringName, Override> overrides; mutable HashMap<StringName, StringName> param_remaps; diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index d7b2292ff5..3661b6c394 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -217,12 +217,4 @@ void Timer::_bind_methods() { BIND_ENUM_CONSTANT(TIMER_PROCESS_IDLE); } -Timer::Timer() { - timer_process_mode = TIMER_PROCESS_IDLE; - autostart = false; - wait_time = 1; - one_shot = false; - time_left = -1; - processing = false; - paused = false; -} +Timer::Timer() {} diff --git a/scene/main/timer.h b/scene/main/timer.h index 0604a2d990..672290cf50 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -36,13 +36,13 @@ class Timer : public Node { GDCLASS(Timer, Node); - float wait_time; - bool one_shot; - bool autostart; - bool processing; - bool paused; + float wait_time = 1.0; + bool one_shot = false; + bool autostart = false; + bool processing = false; + bool paused = false; - double time_left; + double time_left = -1.0; protected: void _notification(int p_what); @@ -78,7 +78,7 @@ public: Timer(); private: - TimerProcessMode timer_process_mode; + TimerProcessMode timer_process_mode = TIMER_PROCESS_IDLE; void _set_process(bool p_process, bool p_force = false); }; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 82053e1557..a0750b2590 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -144,7 +144,6 @@ void ViewportTexture::_bind_methods() { } ViewportTexture::ViewportTexture() { - vp = nullptr; set_local_to_scene(true); } @@ -184,26 +183,6 @@ public: ///////////////////////////////////// -Viewport::GUI::GUI() { - embed_subwindows_hint = false; - embedding_subwindows = false; - - dragging = false; - mouse_focus = nullptr; - forced_mouse_focus = false; - mouse_click_grabber = nullptr; - mouse_focus_mask = 0; - key_focus = nullptr; - mouse_over = nullptr; - drag_mouse_over = nullptr; - - tooltip_control = nullptr; - tooltip_popup = nullptr; - tooltip_label = nullptr; -} - -///////////////////////////////////// - void Viewport::update_worlds() { if (!is_inside_tree()) { return; @@ -468,7 +447,7 @@ void Viewport::_notification(int p_what) { //3D PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create(); - RenderingServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); + RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true); RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0); RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid()); contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create(); @@ -567,280 +546,297 @@ void Viewport::_notification(int p_what) { int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space()); RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); + + for (int i = 0; i < point_count; i++) { + Transform point_transform; + point_transform.origin = points[i]; + RS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform); + } + } + } break; + case NOTIFICATION_WM_MOUSE_EXIT: { + _drop_physics_mouseover(); + + // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not + // drop the gui mouseover here, as a scrollbar may be dragged while the + // mouse is outside the window (without the window having lost focus). + // See bug #39634 + } break; + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { + _drop_physics_mouseover(); + + if (gui.mouse_focus && !gui.forced_mouse_focus) { + _drop_mouse_focus(); } + } break; + } +} + +void Viewport::_process_picking() { + if (!is_inside_tree()) { + return; + } + if (!physics_object_picking) { + return; + } + if (to_screen_rect != Rect2i() && Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) { + return; + } + + _drop_physics_mouseover(true); - if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) { #ifndef _3D_DISABLED - Vector2 last_pos(1e20, 1e20); - CollisionObject3D *last_object = nullptr; - ObjectID last_id; + Vector2 last_pos(1e20, 1e20); + CollisionObject3D *last_object = nullptr; + ObjectID last_id; #endif - PhysicsDirectSpaceState3D::RayResult result; - PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); - - if (physics_has_last_mousepos) { - // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. - // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame - bool has_mouse_event = false; - for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) { - Ref<InputEventMouse> m = E->get(); - if (m.is_valid()) { - has_mouse_event = true; - break; - } - } + PhysicsDirectSpaceState3D::RayResult result; + PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); + + if (physics_has_last_mousepos) { + // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved. + // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame + bool has_mouse_event = false; + for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) { + Ref<InputEventMouse> m = E->get(); + if (m.is_valid()) { + has_mouse_event = true; + break; + } + } - if (!has_mouse_event) { - Ref<InputEventMouseMotion> mm; - mm.instance(); - - mm->set_device(InputEvent::DEVICE_ID_INTERNAL); - mm->set_global_position(physics_last_mousepos); - mm->set_position(physics_last_mousepos); - mm->set_alt(physics_last_mouse_state.alt); - mm->set_shift(physics_last_mouse_state.shift); - mm->set_control(physics_last_mouse_state.control); - mm->set_metakey(physics_last_mouse_state.meta); - mm->set_button_mask(physics_last_mouse_state.mouse_mask); - physics_picking_events.push_back(mm); - } - } + if (!has_mouse_event) { + Ref<InputEventMouseMotion> mm; + mm.instance(); - while (physics_picking_events.size()) { - Ref<InputEvent> ev = physics_picking_events.front()->get(); - physics_picking_events.pop_front(); + mm->set_device(InputEvent::DEVICE_ID_INTERNAL); + mm->set_global_position(physics_last_mousepos); + mm->set_position(physics_last_mousepos); + mm->set_alt(physics_last_mouse_state.alt); + mm->set_shift(physics_last_mouse_state.shift); + mm->set_control(physics_last_mouse_state.control); + mm->set_metakey(physics_last_mouse_state.meta); + mm->set_button_mask(physics_last_mouse_state.mouse_mask); + physics_picking_events.push_back(mm); + } + } - Vector2 pos; - bool is_mouse = false; + while (physics_picking_events.size()) { + Ref<InputEvent> ev = physics_picking_events.front()->get(); + physics_picking_events.pop_front(); - Ref<InputEventMouseMotion> mm = ev; + Vector2 pos; + bool is_mouse = false; - if (mm.is_valid()) { - pos = mm->get_position(); - is_mouse = true; + Ref<InputEventMouseMotion> mm = ev; - physics_has_last_mousepos = true; - physics_last_mousepos = pos; - physics_last_mouse_state.alt = mm->get_alt(); - physics_last_mouse_state.shift = mm->get_shift(); - physics_last_mouse_state.control = mm->get_control(); - physics_last_mouse_state.meta = mm->get_metakey(); - physics_last_mouse_state.mouse_mask = mm->get_button_mask(); - } + if (mm.is_valid()) { + pos = mm->get_position(); + is_mouse = true; - Ref<InputEventMouseButton> mb = ev; + physics_has_last_mousepos = true; + physics_last_mousepos = pos; + physics_last_mouse_state.alt = mm->get_alt(); + physics_last_mouse_state.shift = mm->get_shift(); + physics_last_mouse_state.control = mm->get_control(); + physics_last_mouse_state.meta = mm->get_metakey(); + physics_last_mouse_state.mouse_mask = mm->get_button_mask(); + } - if (mb.is_valid()) { - pos = mb->get_position(); - is_mouse = true; + Ref<InputEventMouseButton> mb = ev; - physics_has_last_mousepos = true; - physics_last_mousepos = pos; - physics_last_mouse_state.alt = mb->get_alt(); - physics_last_mouse_state.shift = mb->get_shift(); - physics_last_mouse_state.control = mb->get_control(); - physics_last_mouse_state.meta = mb->get_metakey(); + if (mb.is_valid()) { + pos = mb->get_position(); + is_mouse = true; - if (mb->is_pressed()) { - physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); - } else { - physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1)); + physics_has_last_mousepos = true; + physics_last_mousepos = pos; + physics_last_mouse_state.alt = mb->get_alt(); + physics_last_mouse_state.shift = mb->get_shift(); + physics_last_mouse_state.control = mb->get_control(); + physics_last_mouse_state.meta = mb->get_metakey(); - // If touch mouse raised, assume we don't know last mouse pos until new events come - if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { - physics_has_last_mousepos = false; - } - } - } + if (mb->is_pressed()) { + physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); + } else { + physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1)); - Ref<InputEventKey> k = ev; - if (k.is_valid()) { - //only for mask - physics_last_mouse_state.alt = k->get_alt(); - physics_last_mouse_state.shift = k->get_shift(); - physics_last_mouse_state.control = k->get_control(); - physics_last_mouse_state.meta = k->get_metakey(); - continue; - } + // If touch mouse raised, assume we don't know last mouse pos until new events come + if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) { + physics_has_last_mousepos = false; + } + } + } - Ref<InputEventScreenDrag> sd = ev; + Ref<InputEventKey> k = ev; + if (k.is_valid()) { + //only for mask + physics_last_mouse_state.alt = k->get_alt(); + physics_last_mouse_state.shift = k->get_shift(); + physics_last_mouse_state.control = k->get_control(); + physics_last_mouse_state.meta = k->get_metakey(); + continue; + } - if (sd.is_valid()) { - pos = sd->get_position(); - } + Ref<InputEventScreenDrag> sd = ev; - Ref<InputEventScreenTouch> st = ev; + if (sd.is_valid()) { + pos = sd->get_position(); + } - if (st.is_valid()) { - pos = st->get_position(); - } + Ref<InputEventScreenTouch> st = ev; - if (ss2d) { - //send to 2D + if (st.is_valid()) { + pos = st->get_position(); + } - uint64_t frame = get_tree()->get_frame(); + if (ss2d) { + //send to 2D - PhysicsDirectSpaceState2D::ShapeResult res[64]; - for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) { - Transform2D canvas_transform; - ObjectID canvas_layer_id; - if (E->get()) { - // A descendant CanvasLayer - canvas_transform = E->get()->get_transform(); - canvas_layer_id = E->get()->get_instance_id(); - } else { - // This Viewport's builtin canvas - canvas_transform = get_canvas_transform(); - canvas_layer_id = ObjectID(); - } + uint64_t frame = get_tree()->get_frame(); - Vector2 point = canvas_transform.affine_inverse().xform(pos); - - int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); - for (int i = 0; i < rc; i++) { - if (res[i].collider_id.is_valid() && res[i].collider) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); - if (co) { - bool send_event = true; - if (is_mouse) { - Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id); - - if (!F) { - physics_2d_mouseover.insert(res[i].collider_id, frame); - co->_mouse_enter(); - } else { - F->get() = frame; - // It was already hovered, so don't send the event if it's faked - if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { - send_event = false; - } - } - } - - if (send_event) { - co->_input_event(this, ev, res[i].shape); - } + PhysicsDirectSpaceState2D::ShapeResult res[64]; + for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) { + Transform2D canvas_transform; + ObjectID canvas_layer_id; + if (E->get()) { + // A descendant CanvasLayer + canvas_transform = E->get()->get_transform(); + canvas_layer_id = E->get()->get_instance_id(); + } else { + // This Viewport's builtin canvas + canvas_transform = get_canvas_transform(); + canvas_layer_id = ObjectID(); + } + + Vector2 point = canvas_transform.affine_inverse().xform(pos); + + int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); + for (int i = 0; i < rc; i++) { + if (res[i].collider_id.is_valid() && res[i].collider) { + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); + if (co && co->can_process()) { + bool send_event = true; + if (is_mouse) { + Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id); + + if (!F) { + physics_2d_mouseover.insert(res[i].collider_id, frame); + co->_mouse_enter(); + } else { + F->get() = frame; + // It was already hovered, so don't send the event if it's faked + if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) { + send_event = false; } } } - } - if (is_mouse) { - List<Map<ObjectID, uint64_t>::Element *> to_erase; - - for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { - if (E->get() != frame) { - Object *o = ObjectDB::get_instance(E->key()); - if (o) { - CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - if (co) { - co->_mouse_exit(); - } - } - to_erase.push_back(E); - } + if (send_event) { + co->_input_event(this, ev, res[i].shape); } + } + } + } + } + + if (is_mouse) { + List<Map<ObjectID, uint64_t>::Element *> to_erase; - while (to_erase.size()) { - physics_2d_mouseover.erase(to_erase.front()->get()); - to_erase.pop_front(); + for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { + if (E->get() != frame) { + Object *o = ObjectDB::get_instance(E->key()); + if (o) { + CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); + if (co) { + co->_mouse_exit(); } } + to_erase.push_back(E); } + } + + while (to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); + } + } + } #ifndef _3D_DISABLED - bool captured = false; - - if (physics_object_capture.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); - if (co && camera) { - _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0); - captured = true; - if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { - physics_object_capture = ObjectID(); - } + bool captured = false; + + if (physics_object_capture.is_valid()) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture)); + if (co && camera) { + _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0); + captured = true; + if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { + physics_object_capture = ObjectID(); + } - } else { - physics_object_capture = ObjectID(); + } else { + physics_object_capture = ObjectID(); + } + } + + if (captured) { + //none + } else if (pos == last_pos) { + if (last_id.is_valid()) { + if (ObjectDB::get_instance(last_id) && last_object) { + //good, exists + _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape); + if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { + physics_object_capture = last_id; + } + } + } + } else { + if (camera) { + Vector3 from = camera->project_ray_origin(pos); + Vector3 dir = camera->project_ray_normal(pos); + + PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space()); + if (space) { + bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); + ObjectID new_collider; + if (col) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); + if (co && co->can_process()) { + _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape); + last_object = co; + last_id = result.collider_id; + new_collider = last_id; + if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { + physics_object_capture = last_id; + } } } - if (captured) { - //none - } else if (pos == last_pos) { - if (last_id.is_valid()) { - if (ObjectDB::get_instance(last_id) && last_object) { - //good, exists - _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape); - if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { - physics_object_capture = last_id; - } + if (is_mouse && new_collider != physics_object_over) { + if (physics_object_over.is_valid()) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); + if (co) { + co->_mouse_exit(); } } - } else { - if (camera) { - Vector3 from = camera->project_ray_origin(pos); - Vector3 dir = camera->project_ray_normal(pos); - - PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space()); - if (space) { - bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); - ObjectID new_collider; - if (col) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider); - if (co) { - _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape); - last_object = co; - last_id = result.collider_id; - new_collider = last_id; - if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { - physics_object_capture = last_id; - } - } - } - if (is_mouse && new_collider != physics_object_over) { - if (physics_object_over.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); - if (co) { - co->_mouse_exit(); - } - } - - if (new_collider.is_valid()) { - CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider)); - if (co) { - co->_mouse_enter(); - } - } - - physics_object_over = new_collider; - } + if (new_collider.is_valid()) { + CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider)); + if (co) { + co->_mouse_enter(); } - - last_pos = pos; } + + physics_object_over = new_collider; } -#endif } - } - - } break; - case NOTIFICATION_WM_MOUSE_EXIT: { - _drop_physics_mouseover(); - - // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not - // drop the gui mouseover here, as a scrollbar may be dragged while the - // mouse is outside the window (without the window having lost focus). - // See bug #39634 - } break; - case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { - _drop_physics_mouseover(); - if (gui.mouse_focus && !gui.forced_mouse_focus) { - _drop_mouse_focus(); + last_pos = pos; } - } break; + } +#endif } } @@ -2582,28 +2578,41 @@ void Viewport::_drop_mouse_focus() { } } -void Viewport::_drop_physics_mouseover() { +void Viewport::_drop_physics_mouseover(bool p_paused_only) { physics_has_last_mousepos = false; - while (physics_2d_mouseover.size()) { - Object *o = ObjectDB::get_instance(physics_2d_mouseover.front()->key()); + List<Map<ObjectID, uint64_t>::Element *> to_erase; + + for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) { + Object *o = ObjectDB::get_instance(E->key()); if (o) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o); - co->_mouse_exit(); + if (co) { + if (p_paused_only && co->can_process()) { + continue; + } + co->_mouse_exit(); + to_erase.push_back(E); + } } - physics_2d_mouseover.erase(physics_2d_mouseover.front()); + } + + while (to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); } #ifndef _3D_DISABLED if (physics_object_over.is_valid()) { CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over)); if (co) { - co->_mouse_exit(); + if (!(p_paused_only && co->can_process())) { + co->_mouse_exit(); + physics_object_over = ObjectID(); + physics_object_capture = ObjectID(); + } } } - - physics_object_over = ObjectID(); - physics_object_capture = ObjectID(); #endif } @@ -3529,6 +3538,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_threshold", "pixels"), &Viewport::set_lod_threshold); ClassDB::bind_method(D_METHOD("get_lod_threshold"), &Viewport::get_lod_threshold); + ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); @@ -3656,26 +3667,10 @@ Viewport::Viewport() { viewport_textures.insert(default_texture.ptr()); default_texture->proxy = RS::get_singleton()->texture_proxy_create(texture_rid); - audio_listener = false; //internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create(); - audio_listener_2d = false; - transparent_bg = false; - parent = nullptr; - listener = nullptr; - camera = nullptr; - override_canvas_transform = false; canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport) - gen_mipmaps = false; - //clear=true; - - physics_object_picking = false; - physics_has_last_mousepos = false; - physics_last_mousepos = Vector2(Math_INF, Math_INF); - - shadow_atlas_16_bits = true; - shadow_atlas_size = 2048; set_shadow_atlas_size(shadow_atlas_size); for (int i = 0; i < 4; i++) { @@ -3694,50 +3689,11 @@ Viewport::Viewport() { unhandled_input_group = "_vp_unhandled_input" + id; unhandled_key_input_group = "_vp_unhandled_key_input" + id; - disable_input = false; - // Window tooltip. - gui.tooltip_timer = -1; - gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers - gui.tooltip_control = nullptr; - gui.tooltip_label = nullptr; - gui.drag_preview = nullptr; - gui.drag_attempted = false; - gui.canvas_sort_index = 0; - gui.roots_order_dirty = false; - gui.mouse_focus = nullptr; - gui.forced_mouse_focus = false; - gui.last_mouse_focus = nullptr; - gui.subwindow_focused = nullptr; - gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED; - - msaa = MSAA_DISABLED; - screen_space_aa = SCREEN_SPACE_AA_DISABLED; - debug_draw = DEBUG_DRAW_DISABLED; - - snap_controls_to_pixels = true; - snap_2d_transforms_to_pixel = false; - snap_2d_vertices_to_pixel = false; - - physics_last_mouse_state.alt = false; - physics_last_mouse_state.control = false; - physics_last_mouse_state.shift = false; - physics_last_mouse_state.meta = false; - physics_last_mouse_state.mouse_mask = 0; - local_input_handled = false; - handle_input_locally = true; - - size_allocated = false; - - default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; - default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - - sdf_oversize = SDF_OVERSIZE_120_PERCENT; - sdf_scale = SDF_SCALE_50_PERCENT; - set_sdf_oversize(SDF_OVERSIZE_120_PERCENT); //set to server + set_sdf_oversize(sdf_oversize); //set to server } Viewport::~Viewport() { @@ -3869,12 +3825,6 @@ void SubViewport::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_ALWAYS); } -SubViewport::SubViewport() { - xr = false; - size_2d_override_stretch = false; - update_mode = UPDATE_WHEN_VISIBLE; - clear_mode = CLEAR_MODE_ALWAYS; -} +SubViewport::SubViewport() {} -SubViewport::~SubViewport() { -} +SubViewport::~SubViewport() {} diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 17d4835c63..2a0026a561 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -56,7 +56,7 @@ class ViewportTexture : public Texture2D { NodePath path; friend class Viewport; - Viewport *vp; + Viewport *vp = nullptr; mutable RID proxy_ph; mutable RID proxy; @@ -186,9 +186,9 @@ public: private: friend class ViewportTexture; - Viewport *parent; + Viewport *parent = nullptr; - Listener3D *listener; + Listener3D *listener = nullptr; Set<Listener3D *> listeners; struct CameraOverrideData { @@ -197,11 +197,11 @@ private: PROJECTION_PERSPECTIVE, PROJECTION_ORTHOGONAL }; - Projection projection; - float fov; - float size; - float z_near; - float z_far; + Projection projection = Projection::PROJECTION_PERSPECTIVE; + float fov = 0.0; + float size = 0.0; + float z_near = 0.0; + float z_far = 0.0; RID rid; operator bool() const { @@ -209,7 +209,7 @@ private: } } camera_override; - Camera3D *camera; + Camera3D *camera = nullptr; Set<Camera3D *> cameras; Set<CanvasLayer *> canvas_layers; @@ -217,13 +217,13 @@ private: RID current_canvas; RID subwindow_canvas; - bool audio_listener; + bool audio_listener = false; RID internal_listener; - bool audio_listener_2d; + bool audio_listener_2d = false; RID internal_listener_2d; - bool override_canvas_transform; + bool override_canvas_transform = false; Transform2D canvas_transform_override; Transform2D canvas_transform; @@ -232,7 +232,7 @@ private: Size2i size; Size2i size_2d_override; - bool size_allocated; + bool size_allocated = false; RID contact_2d_debug; RID contact_3d_debug_multimesh; @@ -240,36 +240,36 @@ private: Rect2 last_vp_rect; - bool transparent_bg; + bool transparent_bg = false; bool filter; - bool gen_mipmaps; + bool gen_mipmaps = false; - bool snap_controls_to_pixels; - bool snap_2d_transforms_to_pixel; - bool snap_2d_vertices_to_pixel; + bool snap_controls_to_pixels = true; + bool snap_2d_transforms_to_pixel = false; + bool snap_2d_vertices_to_pixel = false; - bool physics_object_picking; + bool physics_object_picking = false; List<Ref<InputEvent>> physics_picking_events; ObjectID physics_object_capture; ObjectID physics_object_over; Transform physics_last_object_transform; Transform physics_last_camera_transform; ObjectID physics_last_id; - bool physics_has_last_mousepos; - Vector2 physics_last_mousepos; + bool physics_has_last_mousepos = false; + Vector2 physics_last_mousepos = Vector2(Math_INF, Math_INF); struct { - bool alt; - bool control; - bool shift; - bool meta; - int mouse_mask; + bool alt = false; + bool control = false; + bool shift = false; + bool meta = false; + int mouse_mask = 0; } physics_last_mouse_state; void _collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape); - bool handle_input_locally; - bool local_input_handled; + bool handle_input_locally = true; + bool local_input_handled = false; Map<ObjectID, uint64_t> physics_2d_mouseover; @@ -294,22 +294,22 @@ private: RID texture_rid; - DebugDraw debug_draw; + DebugDraw debug_draw = DEBUG_DRAW_DISABLED; - int shadow_atlas_size; + int shadow_atlas_size = 2048; bool shadow_atlas_16_bits = true; ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; - MSAA msaa; - ScreenSpaceAA screen_space_aa; + MSAA msaa = MSAA_DISABLED; + ScreenSpaceAA screen_space_aa = SCREEN_SPACE_AA_DISABLED; bool use_debanding = false; float lod_threshold = 1.0; Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; - SDFOversize sdf_oversize; - SDFScale sdf_scale; + SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT; + SDFScale sdf_scale = SDF_SCALE_50_PERCENT; enum SubWindowDrag { SUB_WINDOW_DRAG_DISABLED, @@ -332,60 +332,58 @@ private: }; struct SubWindow { - Window *window; + Window *window = nullptr; RID canvas_item; }; struct GUI { // info used when this is a window - bool forced_mouse_focus; //used for menu buttons - bool key_event_accepted; - Control *mouse_focus; - Control *last_mouse_focus; - Control *mouse_click_grabber; - int mouse_focus_mask; - Control *key_focus; - Control *mouse_over; - Control *drag_mouse_over; + bool forced_mouse_focus = false; //used for menu buttons + bool key_event_accepted = false; + Control *mouse_focus = nullptr; + Control *last_mouse_focus = nullptr; + Control *mouse_click_grabber = nullptr; + int mouse_focus_mask = 0; + Control *key_focus = nullptr; + Control *mouse_over = nullptr; + Control *drag_mouse_over = nullptr; Vector2 drag_mouse_over_pos; - Control *tooltip_control; - Window *tooltip_popup; - Label *tooltip_label; + Control *tooltip_control = nullptr; + Window *tooltip_popup = nullptr; + Label *tooltip_label = nullptr; Point2 tooltip_pos; Point2 last_mouse_pos; Point2 drag_accum; - bool drag_attempted; + bool drag_attempted = false; Variant drag_data; - Control *drag_preview; - float tooltip_timer; - float tooltip_delay; + Control *drag_preview = nullptr; + float tooltip_timer = -1.0; + float tooltip_delay = 0.0; Transform2D focus_inv_xform; - bool roots_order_dirty; + bool roots_order_dirty = false; List<Control *> roots; - int canvas_sort_index; //for sorting items with canvas as root - bool dragging; - bool embed_subwindows_hint; - bool embedding_subwindows; + int canvas_sort_index = 0; //for sorting items with canvas as root + bool dragging = false; + bool embed_subwindows_hint = false; + bool embedding_subwindows = false; - Window *subwindow_focused; - SubWindowDrag subwindow_drag; + Window *subwindow_focused = nullptr; + SubWindowDrag subwindow_drag = SUB_WINDOW_DRAG_DISABLED; Vector2 subwindow_drag_from; Vector2 subwindow_drag_pos; Rect2i subwindow_drag_close_rect; - bool subwindow_drag_close_inside; + bool subwindow_drag_close_inside = false; SubWindowResize subwindow_resize_mode; Rect2i subwindow_resize_from_rect; Vector<SubWindow> sub_windows; - - GUI(); } gui; - DefaultCanvasItemTextureFilter default_canvas_item_texture_filter; - DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat; + DefaultCanvasItemTextureFilter default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; + DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - bool disable_input; + bool disable_input = false; void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input); void _gui_call_notification(Control *p_control, int p_what); @@ -450,7 +448,7 @@ private: void _canvas_layer_remove(CanvasLayer *p_canvas_layer); void _drop_mouse_focus(); - void _drop_physics_mouseover(); + void _drop_physics_mouseover(bool p_paused_only = false); void _update_canvas_items(Node *p_node); @@ -479,6 +477,7 @@ protected: bool _is_size_allocated() const; void _notification(int p_what); + void _process_picking(); static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; @@ -650,10 +649,10 @@ public: }; private: - UpdateMode update_mode; - ClearMode clear_mode; - bool xr; - bool size_2d_override_stretch; + UpdateMode update_mode = UPDATE_WHEN_VISIBLE; + ClearMode clear_mode = CLEAR_MODE_ALWAYS; + bool xr = false; + bool size_2d_override_stretch = false; protected: static void _bind_methods(); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 0a541a2d07..f39823736b 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1466,11 +1466,6 @@ void Window::_bind_methods() { } Window::Window() { - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; - } - content_scale_mode = CONTENT_SCALE_MODE_DISABLED; - content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED); } diff --git a/scene/main/window.h b/scene/main/window.h index 2ffeff03ff..38846ed00e 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -90,7 +90,7 @@ private: mutable Size2i min_size; mutable Size2i max_size; mutable Mode mode = MODE_WINDOWED; - mutable bool flags[FLAG_MAX]; + mutable bool flags[FLAG_MAX] = {}; bool visible = true; bool focused = false; @@ -106,8 +106,8 @@ private: void _update_child_controls(); Size2i content_scale_size; - ContentScaleMode content_scale_mode; - ContentScaleAspect content_scale_aspect; + ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED; + ContentScaleAspect content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE; void _make_window(); void _clear_window(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index c349d090d8..b14c44689e 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -557,19 +557,14 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeDeterminant>(); ClassDB::register_class<VisualShaderNodeScalarDerivativeFunc>(); ClassDB::register_class<VisualShaderNodeVectorDerivativeFunc>(); - ClassDB::register_class<VisualShaderNodeScalarClamp>(); - ClassDB::register_class<VisualShaderNodeVectorClamp>(); + ClassDB::register_class<VisualShaderNodeClamp>(); ClassDB::register_class<VisualShaderNodeFaceForward>(); ClassDB::register_class<VisualShaderNodeOuterProduct>(); - ClassDB::register_class<VisualShaderNodeVectorScalarStep>(); - ClassDB::register_class<VisualShaderNodeScalarSmoothStep>(); - ClassDB::register_class<VisualShaderNodeVectorSmoothStep>(); - ClassDB::register_class<VisualShaderNodeVectorScalarSmoothStep>(); + ClassDB::register_class<VisualShaderNodeSmoothStep>(); + ClassDB::register_class<VisualShaderNodeStep>(); ClassDB::register_class<VisualShaderNodeVectorDistance>(); ClassDB::register_class<VisualShaderNodeVectorRefract>(); - ClassDB::register_class<VisualShaderNodeScalarInterp>(); - ClassDB::register_class<VisualShaderNodeVectorInterp>(); - ClassDB::register_class<VisualShaderNodeVectorScalarMix>(); + ClassDB::register_class<VisualShaderNodeMix>(); ClassDB::register_class<VisualShaderNodeVectorCompose>(); ClassDB::register_class<VisualShaderNodeTransformCompose>(); ClassDB::register_class<VisualShaderNodeVectorDecompose>(); @@ -595,7 +590,6 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeCubemapUniform>(); ClassDB::register_class<VisualShaderNodeIf>(); ClassDB::register_class<VisualShaderNodeSwitch>(); - ClassDB::register_class<VisualShaderNodeScalarSwitch>(); ClassDB::register_class<VisualShaderNodeFresnel>(); ClassDB::register_class<VisualShaderNodeExpression>(); ClassDB::register_class<VisualShaderNodeGlobalExpression>(); @@ -935,6 +929,16 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarClamp", "VisualShaderNodeClamp"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorClamp", "VisualShaderNodeClamp"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarInterp", "VisualShaderNodeMix"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorInterp", "VisualShaderNodeMix"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarMix", "VisualShaderNodeMix"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarSmoothStep", "VisualShaderNodeSmoothStep"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorSmoothStep", "VisualShaderNodeSmoothStep"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarSmoothStep", "VisualShaderNodeSmoothStep"); + ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarStep", "VisualShaderNodeStep"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch"); ClassDB::add_compatibility_class("World", "World3D"); ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); ClassDB::add_compatibility_class("Light2D", "PointLight2D"); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 796fe1d106..cc1dafd0db 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -580,6 +580,10 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const { } } +void Animation::reset_state() { + clear(); +} + int Animation::add_track(TrackType p_type, int p_at_pos) { if (p_at_pos < 0 || p_at_pos >= tracks.size()) { p_at_pos = tracks.size(); @@ -1604,7 +1608,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola bool result = true; int next = 0; - float c = 0; + float c = 0.0; // prepare for all cases of interpolation if (loop && p_loop_wrap) { @@ -2278,8 +2282,8 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const { int iterations = 10; float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes - float low = 0; // 0% of the current animation segment - float high = 1; // 100% of the current animation segment + float low = 0.0; // 0% of the current animation segment + float high = 1.0; // 100% of the current animation segment float middle; Vector2 start(0, bt->values[idx].value.value); @@ -2836,7 +2840,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons erase = true; } else { erase = true; - real_t lt = -1; + real_t lt = -1.0; for (int j = 0; j < 3; j++) { //search for t on first, one must be it if (t[j] != -1) { @@ -2919,11 +2923,7 @@ void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err } } -Animation::Animation() { - step = 0.1; - loop = false; - length = 1; -} +Animation::Animation() {} Animation::~Animation() { for (int i = 0; i < tracks.size(); i++) { diff --git a/scene/resources/animation.h b/scene/resources/animation.h index fa374e6ad2..fd22cc445c 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -65,28 +65,19 @@ public: private: struct Track { - TrackType type; - InterpolationType interpolation; - bool loop_wrap; + TrackType type = TrackType::TYPE_ANIMATION; + InterpolationType interpolation = INTERPOLATION_LINEAR; + bool loop_wrap = true; NodePath path; // path to something - bool imported; - bool enabled; - Track() { - interpolation = INTERPOLATION_LINEAR; - imported = false; - loop_wrap = true; - enabled = true; - } + bool imported = false; + bool enabled = false; + Track() {} virtual ~Track() {} }; struct Key { - float transition; - float time; // time in secs - Key() { - transition = 1; - time = 0; - } + float transition = 1.0; + float time = 0.0; // time in secs }; // transform key holds either Vector3 or Quaternion @@ -112,13 +103,12 @@ private: /* PROPERTY VALUE TRACK */ struct ValueTrack : public Track { - UpdateMode update_mode; - bool update_on_seek; + UpdateMode update_mode = UPDATE_CONTINUOUS; + bool update_on_seek = false; Vector<TKey<Variant>> values; ValueTrack() { type = TYPE_VALUE; - update_mode = UPDATE_CONTINUOUS; } }; @@ -139,7 +129,7 @@ private: struct BezierKey { Vector2 in_handle; //relative (x always <0) Vector2 out_handle; //relative (x always >0) - float value; + float value = 0.0; }; struct BezierTrack : public Track { @@ -154,11 +144,9 @@ private: struct AudioKey { RES stream; - float start_offset; //offset from start - float end_offset; //offset from end, if 0 then full length or infinite + float start_offset = 0.0; //offset from start + float end_offset = 0.0; //offset from end, if 0 then full length or infinite AudioKey() { - start_offset = 0; - end_offset = 0; } }; @@ -217,9 +205,9 @@ private: _FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const; _FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const; - float length; - float step; - bool loop; + float length = 1.0; + float step = 0.1; + bool loop = false; // bind helpers private: @@ -264,6 +252,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + static void _bind_methods(); public: diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index 8fdb004e65..06a91fb2f8 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -403,11 +403,7 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in } } -AudioStreamPlaybackSample::AudioStreamPlaybackSample() { - active = false; - offset = 0; - sign = 1; -} +AudioStreamPlaybackSample::AudioStreamPlaybackSample() {} ///////////////////// @@ -651,16 +647,7 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_BACKWARD); } -AudioStreamSample::AudioStreamSample() { - format = FORMAT_8_BITS; - loop_mode = LOOP_DISABLED; - stereo = false; - loop_begin = 0; - loop_end = 0; - mix_rate = 44100; - data = nullptr; - data_bytes = 0; -} +AudioStreamSample::AudioStreamSample() {} AudioStreamSample::~AudioStreamSample() { if (data) { diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index ba475c0888..70b8ba79ad 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -44,19 +44,19 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback { }; struct IMA_ADPCM_State { - int16_t step_index; - int32_t predictor; + int16_t step_index = 0; + int32_t predictor = 0; /* values at loop point */ - int16_t loop_step_index; - int32_t loop_predictor; - int32_t last_nibble; - int32_t loop_pos; - int32_t window_ofs; + int16_t loop_step_index = 0; + int32_t loop_predictor = 0; + int32_t last_nibble = 0; + int32_t loop_pos = 0; + int32_t window_ofs = 0; } ima_adpcm[2]; - int64_t offset; - int sign; - bool active; + int64_t offset = 0; + int sign = 1; + bool active = false; friend class AudioStreamSample; Ref<AudioStreamSample> base; @@ -103,14 +103,14 @@ private: DATA_PAD = 16 //padding for interpolation }; - Format format; - LoopMode loop_mode; - bool stereo; - int loop_begin; - int loop_end; - int mix_rate; - void *data; - uint32_t data_bytes; + Format format = FORMAT_8_BITS; + LoopMode loop_mode = LOOP_DISABLED; + bool stereo = false; + int loop_begin = 0; + int loop_end = 0; + int mix_rate = 44100; + void *data = nullptr; + uint32_t data_bytes = 0; protected: static void _bind_methods(); diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index dfb7a1fdfb..8ffc7b4b4c 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -346,7 +346,7 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) { } int index = -1; - float dist = 0; + float dist = 0.0; //not looping first and last point for (size_t i = 1, size = v.size(); i < size - 1; ++i) { float cdist = perpendicular_distance(v[i], v[0], v[v.size() - 1]); @@ -406,8 +406,8 @@ static Vector<Vector2> reduce(const Vector<Vector2> &points, const Rect2i &rect, struct FillBitsStackEntry { Point2i pos; - int i; - int j; + int i = 0; + int j = 0; }; static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) { @@ -677,9 +677,6 @@ void BitMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); } -BitMap::BitMap() { - width = 0; - height = 0; -} +BitMap::BitMap() {} ////////////////////////////////////// diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index 7414265cee..68fd0b999a 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -40,8 +40,8 @@ class BitMap : public Resource { OBJ_SAVE_TYPE(BitMap); Vector<uint8_t> bitmask; - int width; - int height; + int width = 0; + int height = 0; Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const; diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp index fadbf21e43..6e7adc0bd7 100644 --- a/scene/resources/box_shape_3d.cpp +++ b/scene/resources/box_shape_3d.cpp @@ -60,7 +60,6 @@ void BoxShape3D::set_size(const Vector3 &p_size) { size = p_size; _update_shape(); notify_change_to_owners(); - _change_notify("size"); } Vector3 BoxShape3D::get_size() const { diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp index 695b14939f..4038338e1e 100644 --- a/scene/resources/camera_effects.cpp +++ b/scene/resources/camera_effects.cpp @@ -41,7 +41,7 @@ RID CameraEffects::get_rid() const { void CameraEffects::set_dof_blur_far_enabled(bool p_enabled) { dof_blur_far_enabled = p_enabled; _update_dof_blur(); - _change_notify(); + notify_property_list_changed(); } bool CameraEffects::is_dof_blur_far_enabled() const { @@ -69,7 +69,7 @@ float CameraEffects::get_dof_blur_far_transition() const { void CameraEffects::set_dof_blur_near_enabled(bool p_enabled) { dof_blur_near_enabled = p_enabled; _update_dof_blur(); - _change_notify(); + notify_property_list_changed(); } bool CameraEffects::is_dof_blur_near_enabled() const { diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h index cf12b6d3c0..28aa6b8660 100644 --- a/scene/resources/camera_effects.h +++ b/scene/resources/camera_effects.h @@ -42,12 +42,12 @@ private: // DOF blur bool dof_blur_far_enabled = false; - float dof_blur_far_distance = 10; - float dof_blur_far_transition = 5; + float dof_blur_far_distance = 10.0; + float dof_blur_far_transition = 5.0; bool dof_blur_near_enabled = false; - float dof_blur_near_distance = 2; - float dof_blur_near_transition = 1; + float dof_blur_near_distance = 2.0; + float dof_blur_near_transition = 1.0; float dof_blur_amount = 0.1; void _update_dof_blur(); diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 6041f4a8b0..3725d855f4 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -36,12 +36,13 @@ Vector<Vector2> CapsuleShape2D::_get_points() const { Vector<Vector2> points; + const real_t turn_step = Math_TAU / 24.0; for (int i = 0; i < 24; i++) { Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5); - points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs); + points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * get_radius() + ofs); if (i == 6 || i == 18) { - points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs); + points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * get_radius() - ofs); } } @@ -111,7 +112,5 @@ void CapsuleShape2D::_bind_methods() { CapsuleShape2D::CapsuleShape2D() : Shape2D(PhysicsServer2D::get_singleton()->capsule_shape_create()) { - radius = 10; - height = 20; _update_shape(); } diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h index 8c8c1b259b..439b67e8c3 100644 --- a/scene/resources/capsule_shape_2d.h +++ b/scene/resources/capsule_shape_2d.h @@ -36,8 +36,8 @@ class CapsuleShape2D : public Shape2D { GDCLASS(CapsuleShape2D, Shape2D); - real_t height; - real_t radius; + real_t height = 20.0; + real_t radius = 10.0; void _update_shape(); Vector<Vector2> _get_points() const; diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index a0b454a00f..226fe1ecd2 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -82,7 +82,6 @@ void CapsuleShape3D::set_radius(float p_radius) { radius = p_radius; _update_shape(); notify_change_to_owners(); - _change_notify("radius"); } float CapsuleShape3D::get_radius() const { @@ -93,7 +92,6 @@ void CapsuleShape3D::set_height(float p_height) { height = p_height; _update_shape(); notify_change_to_owners(); - _change_notify("height"); } float CapsuleShape3D::get_height() const { @@ -112,7 +110,5 @@ void CapsuleShape3D::_bind_methods() { CapsuleShape3D::CapsuleShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CAPSULE)) { - radius = 1.0; - height = 1.0; _update_shape(); } diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h index b5b8912445..25645ecf9d 100644 --- a/scene/resources/capsule_shape_3d.h +++ b/scene/resources/capsule_shape_3d.h @@ -35,8 +35,8 @@ class CapsuleShape3D : public Shape3D { GDCLASS(CapsuleShape3D, Shape3D); - float radius; - float height; + float radius = 1.0; + float height = 1.0; protected: static void _bind_methods(); diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index ba49587d9d..735bf47482 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -71,8 +71,9 @@ real_t CircleShape2D::get_enclosing_radius() const { void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector<Vector2> points; + const real_t turn_step = Math_TAU / 24.0; for (int i = 0; i < 24; i++) { - points.push_back(Vector2(Math::cos(i * Math_PI * 2 / 24.0), Math::sin(i * Math_PI * 2 / 24.0)) * get_radius()); + points.push_back(Vector2(Math::cos(i * turn_step), Math::sin(i * turn_step)) * get_radius()); } Vector<Color> col; @@ -82,6 +83,5 @@ void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) { CircleShape2D::CircleShape2D() : Shape2D(PhysicsServer2D::get_singleton()->circle_shape_create()) { - radius = 10; _update_shape(); } diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h index a066b773ef..333f299236 100644 --- a/scene/resources/circle_shape_2d.h +++ b/scene/resources/circle_shape_2d.h @@ -36,7 +36,7 @@ class CircleShape2D : public Shape2D { GDCLASS(CircleShape2D, Shape2D); - real_t radius; + real_t radius = 10.0; void _update_shape(); protected: diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp index 3d6df3bb9c..0c767c8a52 100644 --- a/scene/resources/concave_polygon_shape_2d.cpp +++ b/scene/resources/concave_polygon_shape_2d.cpp @@ -98,7 +98,7 @@ Rect2 ConcavePolygonShape2D::get_rect() const { real_t ConcavePolygonShape2D::get_enclosing_radius() const { Vector<Vector2> data = get_segments(); const Vector2 *read = data.ptr(); - real_t r = 0; + real_t r = 0.0; for (int i(0); i < data.size(); i++) { r = MAX(read[i].length_squared(), r); } diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp index 358c99ad09..f067695d7d 100644 --- a/scene/resources/concave_polygon_shape_3d.cpp +++ b/scene/resources/concave_polygon_shape_3d.cpp @@ -63,7 +63,7 @@ Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const { real_t ConcavePolygonShape3D::get_enclosing_radius() const { Vector<Vector3> data = get_faces(); const Vector3 *read = data.ptr(); - real_t r = 0; + real_t r = 0.0; for (int i(0); i < data.size(); i++) { r = MAX(read[i].length_squared(), r); } diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index 656e064356..b4b200a7ff 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -91,7 +91,7 @@ Rect2 ConvexPolygonShape2D::get_rect() const { } real_t ConvexPolygonShape2D::get_enclosing_radius() const { - real_t r = 0; + real_t r = 0.0; for (int i(0); i < get_points().size(); i++) { r = MAX(get_points()[i].length_squared(), r); } diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp index 770d547231..9e030bc077 100644 --- a/scene/resources/convex_polygon_shape_3d.cpp +++ b/scene/resources/convex_polygon_shape_3d.cpp @@ -56,7 +56,7 @@ Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const { real_t ConvexPolygonShape3D::get_enclosing_radius() const { Vector<Vector3> data = get_points(); const Vector3 *read = data.ptr(); - real_t r = 0; + real_t r = 0.0; for (int i(0); i < data.size(); i++) { r = MAX(read[i].length_squared(), r); } diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 123c77a036..bc479e557a 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -47,11 +47,6 @@ static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed"; Curve::Curve() { - _bake_resolution = 100; - _baked_cache_dirty = false; - _min_value = 0; - _max_value = 1; - _minmax_set_once = 0b00; } int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) { @@ -683,7 +678,7 @@ void Curve2D::_bake() const { for (int i = 0; i < points.size() - 1; i++) { float step = 0.1; // at least 10 substeps ought to be enough? - float p = 0; + float p = 0.0; while (p < 1.0) { float np = p + step; @@ -993,12 +988,9 @@ void Curve2D::_bind_methods() { } Curve2D::Curve2D() { - baked_cache_dirty = false; - baked_max_ofs = 0; /* add_point(Vector2(-1,0,0)); add_point(Vector2(0,2,0)); add_point(Vector2(0,3,5));*/ - bake_interval = 5; } /***********************************************************************************/ @@ -1178,7 +1170,7 @@ void Curve3D::_bake() const { for (int i = 0; i < points.size() - 1; i++) { float step = 0.1; // at least 10 substeps ought to be enough? - float p = 0; + float p = 0.0; while (p < 1.0) { float np = p + step; @@ -1669,11 +1661,7 @@ void Curve3D::_bind_methods() { } Curve3D::Curve3D() { - baked_cache_dirty = false; - baked_max_ofs = 0; /* add_point(Vector3(-1,0,0)); add_point(Vector3(0,2,0)); add_point(Vector3(0,3,5));*/ - bake_interval = 0.2; - up_vector_enabled = true; } diff --git a/scene/resources/curve.h b/scene/resources/curve.h index f33f3c5abe..402c893cd8 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -51,21 +51,17 @@ public: struct Point { Vector2 pos; - real_t left_tangent; - real_t right_tangent; - TangentMode left_mode; - TangentMode right_mode; + real_t left_tangent = 0.0; + real_t right_tangent = 0.0; + TangentMode left_mode = TANGENT_FREE; + TangentMode right_mode = TANGENT_FREE; Point() { - left_tangent = 0; - right_tangent = 0; - left_mode = TANGENT_FREE; - right_mode = TANGENT_FREE; } Point(Vector2 p_pos, - real_t p_left = 0, - real_t p_right = 0, + real_t p_left = 0.0, + real_t p_right = 0.0, TangentMode p_left_mode = TANGENT_FREE, TangentMode p_right_mode = TANGENT_FREE) { pos = p_pos; @@ -137,12 +133,12 @@ private: void mark_dirty(); Vector<Point> _points; - bool _baked_cache_dirty; + bool _baked_cache_dirty = false; Vector<real_t> _baked_cache; - int _bake_resolution; - float _min_value; - float _max_value; - int _minmax_set_once; // Encodes whether min and max have been set a first time, first bit for min and second for max. + int _bake_resolution = 100; + float _min_value = 0.0; + float _max_value = 1.0; + int _minmax_set_once = 0b00; // Encodes whether min and max have been set a first time, first bit for min and second for max. }; VARIANT_ENUM_CAST(Curve::TangentMode) @@ -159,17 +155,17 @@ class Curve2D : public Resource { Vector<Point> points; struct BakedPoint { - float ofs; + float ofs = 0.0; Vector2 point; }; - mutable bool baked_cache_dirty; + mutable bool baked_cache_dirty = false; mutable PackedVector2Array baked_point_cache; - mutable float baked_max_ofs; + mutable float baked_max_ofs = 0.0; void _bake() const; - float bake_interval; + float bake_interval = 5.0; void _bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const; Dictionary _get_data() const; @@ -214,28 +210,26 @@ class Curve3D : public Resource { Vector3 in; Vector3 out; Vector3 pos; - float tilt; - - Point() { tilt = 0; } + float tilt = 0.0; }; Vector<Point> points; struct BakedPoint { - float ofs; + float ofs = 0.0; Vector3 point; }; - mutable bool baked_cache_dirty; + mutable bool baked_cache_dirty = false; mutable PackedVector3Array baked_point_cache; mutable PackedFloat32Array baked_tilt_cache; mutable PackedVector3Array baked_up_vector_cache; - mutable float baked_max_ofs; + mutable float baked_max_ofs = 0.0; void _bake() const; - float bake_interval; - bool up_vector_enabled; + float bake_interval = 0.2; + bool up_vector_enabled = true; void _bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const; Dictionary _get_data() const; diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp index 3e9cdca872..63bdc8d26d 100644 --- a/scene/resources/cylinder_shape_3d.cpp +++ b/scene/resources/cylinder_shape_3d.cpp @@ -75,7 +75,6 @@ void CylinderShape3D::set_radius(float p_radius) { radius = p_radius; _update_shape(); notify_change_to_owners(); - _change_notify("radius"); } float CylinderShape3D::get_radius() const { @@ -86,7 +85,6 @@ void CylinderShape3D::set_height(float p_height) { height = p_height; _update_shape(); notify_change_to_owners(); - _change_notify("height"); } float CylinderShape3D::get_height() const { @@ -105,7 +103,5 @@ void CylinderShape3D::_bind_methods() { CylinderShape3D::CylinderShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CYLINDER)) { - radius = 1.0; - height = 2.0; _update_shape(); } diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h index 93e8345727..d1b8364672 100644 --- a/scene/resources/cylinder_shape_3d.h +++ b/scene/resources/cylinder_shape_3d.h @@ -35,8 +35,8 @@ class CylinderShape3D : public Shape3D { GDCLASS(CylinderShape3D, Shape3D); - float radius; - float height; + float radius = 1.0; + float height = 2.0; protected: static void _bind_methods(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index a0b65e9799..e66de82ed9 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -43,7 +43,7 @@ typedef Map<const void *, Ref<ImageTexture>> TexCacheMap; static TexCacheMap *tex_cache; -static float scale = 1; +static float scale = 1.0; template <class T> static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) { @@ -394,7 +394,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("clear_button_color", "LineEdit", control_font_color); theme->set_color("clear_button_color_pressed", "LineEdit", control_font_pressed_color); - theme->set_constant("minimum_spaces", "LineEdit", 12 * scale); + theme->set_constant("minimum_character_width", "LineEdit", 4); theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png)); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index b7b5f72fcd..6f6af93848 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -44,7 +44,7 @@ RID Environment::get_rid() const { void Environment::set_background(BGMode p_bg) { bg_mode = p_bg; RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg)); - _change_notify(); + notify_property_list_changed(); if (bg_mode != BG_SKY) { set_fog_aerial_perspective(0.0); } @@ -138,7 +138,7 @@ Color Environment::get_ambient_light_color() const { void Environment::set_ambient_source(AmbientSource p_source) { ambient_source = p_source; _update_ambient_light(); - _change_notify(); + notify_property_list_changed(); } Environment::AmbientSource Environment::get_ambient_source() const { @@ -166,7 +166,7 @@ float Environment::get_ambient_light_sky_contribution() const { void Environment::set_reflection_source(ReflectionSource p_source) { reflection_source = p_source; _update_ambient_light(); - _change_notify(); + notify_property_list_changed(); } Environment::ReflectionSource Environment::get_reflection_source() const { @@ -224,7 +224,7 @@ float Environment::get_tonemap_white() const { void Environment::set_tonemap_auto_exposure_enabled(bool p_enabled) { tonemap_auto_exposure_enabled = p_enabled; _update_tonemap(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_tonemap_auto_exposure_enabled() const { @@ -285,7 +285,7 @@ void Environment::_update_tonemap() { void Environment::set_ssr_enabled(bool p_enabled) { ssr_enabled = p_enabled; _update_ssr(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_ssr_enabled() const { @@ -343,7 +343,7 @@ void Environment::_update_ssr() { void Environment::set_ssao_enabled(bool p_enabled) { ssao_enabled = p_enabled; _update_ssao(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_ssao_enabled() const { @@ -458,8 +458,6 @@ Environment::SDFGICascades Environment::get_sdfgi_cascades() const { void Environment::set_sdfgi_min_cell_size(float p_size) { sdfgi_min_cell_size = p_size; - _change_notify("sdfgi_max_distance"); - _change_notify("sdfgi_cascade0_distance"); _update_sdfgi(); } @@ -475,8 +473,6 @@ void Environment::set_sdfgi_max_distance(float p_distance) { p_distance *= 0.5; //halve for each cascade } sdfgi_min_cell_size = p_distance; - _change_notify("sdfgi_min_cell_size"); - _change_notify("sdfgi_cascade0_distance"); _update_sdfgi(); } @@ -493,8 +489,6 @@ float Environment::get_sdfgi_max_distance() const { void Environment::set_sdfgi_cascade0_distance(float p_distance) { sdfgi_min_cell_size = p_distance / 64.0; - _change_notify("sdfgi_min_cell_size"); - _change_notify("sdfgi_max_distance"); _update_sdfgi(); } @@ -520,13 +514,12 @@ bool Environment::is_sdfgi_using_occlusion() const { return sdfgi_use_occlusion; } -void Environment::set_sdfgi_use_multi_bounce(bool p_enabled) { - sdfgi_use_multibounce = p_enabled; +void Environment::set_sdfgi_bounce_feedback(float p_amount) { + sdfgi_bounce_feedback = p_amount; _update_sdfgi(); } - -bool Environment::is_sdfgi_using_multi_bounce() const { - return sdfgi_use_multibounce; +float Environment::get_sdfgi_bounce_feedback() const { + return sdfgi_bounce_feedback; } void Environment::set_sdfgi_read_sky_light(bool p_enabled) { @@ -573,7 +566,7 @@ void Environment::_update_sdfgi() { sdfgi_min_cell_size, RS::EnvironmentSDFGIYScale(sdfgi_y_scale), sdfgi_use_occlusion, - sdfgi_use_multibounce, + sdfgi_bounce_feedback, sdfgi_read_sky_light, sdfgi_energy, sdfgi_normal_bias, @@ -585,7 +578,7 @@ void Environment::_update_sdfgi() { void Environment::set_glow_enabled(bool p_enabled) { glow_enabled = p_enabled; _update_glow(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_glow_enabled() const { @@ -655,7 +648,7 @@ float Environment::get_glow_bloom() const { void Environment::set_glow_blend_mode(GlowBlendMode p_mode) { glow_blend_mode = p_mode; _update_glow(); - _change_notify(); + notify_property_list_changed(); } Environment::GlowBlendMode Environment::get_glow_blend_mode() const { @@ -723,7 +716,7 @@ void Environment::_update_glow() { void Environment::set_fog_enabled(bool p_enabled) { fog_enabled = p_enabled; _update_fog(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_fog_enabled() const { @@ -797,13 +790,13 @@ void Environment::_update_fog() { // Volumetric Fog void Environment::_update_volumetric_fog() { - RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter)); + RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount); } void Environment::set_volumetric_fog_enabled(bool p_enable) { volumetric_fog_enabled = p_enable; _update_volumetric_fog(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_volumetric_fog_enabled() const { @@ -854,13 +847,20 @@ float Environment::get_volumetric_fog_gi_inject() const { return volumetric_fog_gi_inject; } -void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) { - volumetric_fog_shadow_filter = p_filter; +void Environment::set_volumetric_fog_temporal_reprojection_enabled(bool p_enable) { + volumetric_fog_temporal_reproject = p_enable; + _update_volumetric_fog(); +} +bool Environment::is_volumetric_fog_temporal_reprojection_enabled() const { + return volumetric_fog_temporal_reproject; +} +void Environment::set_volumetric_fog_temporal_reprojection_amount(float p_amount) { + volumetric_fog_temporal_reproject_amount = p_amount; _update_volumetric_fog(); } -Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_filter() const { - return volumetric_fog_shadow_filter; +float Environment::get_volumetric_fog_temporal_reprojection_amount() const { + return volumetric_fog_temporal_reproject_amount; } // Adjustment @@ -868,7 +868,7 @@ Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_fi void Environment::set_adjustment_enabled(bool p_enabled) { adjustment_enabled = p_enabled; _update_adjustment(); - _change_notify(); + notify_property_list_changed(); } bool Environment::is_adjustment_enabled() const { @@ -1200,8 +1200,8 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_sdfgi_y_scale"), &Environment::get_sdfgi_y_scale); ClassDB::bind_method(D_METHOD("set_sdfgi_use_occlusion", "enable"), &Environment::set_sdfgi_use_occlusion); ClassDB::bind_method(D_METHOD("is_sdfgi_using_occlusion"), &Environment::is_sdfgi_using_occlusion); - ClassDB::bind_method(D_METHOD("set_sdfgi_use_multi_bounce", "enable"), &Environment::set_sdfgi_use_multi_bounce); - ClassDB::bind_method(D_METHOD("is_sdfgi_using_multi_bounce"), &Environment::is_sdfgi_using_multi_bounce); + ClassDB::bind_method(D_METHOD("set_sdfgi_bounce_feedback", "amount"), &Environment::set_sdfgi_bounce_feedback); + ClassDB::bind_method(D_METHOD("get_sdfgi_bounce_feedback"), &Environment::get_sdfgi_bounce_feedback); ClassDB::bind_method(D_METHOD("set_sdfgi_read_sky_light", "enable"), &Environment::set_sdfgi_read_sky_light); ClassDB::bind_method(D_METHOD("is_sdfgi_reading_sky_light"), &Environment::is_sdfgi_reading_sky_light); ClassDB::bind_method(D_METHOD("set_sdfgi_energy", "amount"), &Environment::set_sdfgi_energy); @@ -1213,9 +1213,9 @@ void Environment::_bind_methods() { ADD_GROUP("SDFGI", "sdfgi_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_enabled"), "set_sdfgi_enabled", "is_sdfgi_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_multi_bounce"), "set_sdfgi_use_multi_bounce", "is_sdfgi_using_multi_bounce"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_occlusion"), "set_sdfgi_use_occlusion", "is_sdfgi_using_occlusion"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_read_sky_light"), "set_sdfgi_read_sky_light", "is_sdfgi_reading_sky_light"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_bounce_feedback", PROPERTY_HINT_RANGE, "0,1.99,0.01"), "set_sdfgi_bounce_feedback", "get_sdfgi_bounce_feedback"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_ENUM, "4 Cascades,6 Cascades,8 Cascades"), "set_sdfgi_cascades", "get_sdfgi_cascades"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); @@ -1317,8 +1317,10 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread); ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject); ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject); - ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter); - ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled); + ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_temporal_reprojection_amount"), &Environment::get_volumetric_fog_temporal_reprojection_amount); ADD_GROUP("Volumetric Fog", "volumetric_fog_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled"), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled"); @@ -1328,7 +1330,9 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter"); + ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.0,0.999,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount"); // Adjustment @@ -1417,7 +1421,7 @@ Environment::Environment() { _update_fog(); _update_adjustment(); _update_volumetric_fog(); - _change_notify(); + notify_property_list_changed(); } Environment::~Environment() { diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 1676a28b39..0df2c3cc27 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -103,7 +103,7 @@ private: // Background BGMode bg_mode = BG_CLEAR_COLOR; Ref<Sky> bg_sky; - float bg_sky_custom_fov = 0; + float bg_sky_custom_fov = 0.0; Vector3 bg_sky_rotation; Color bg_color; float bg_energy = 1.0; @@ -125,7 +125,7 @@ private: float tonemap_white = 1.0; bool tonemap_auto_exposure_enabled = false; float tonemap_auto_exposure_min = 0.05; - float tonemap_auto_exposure_max = 8; + float tonemap_auto_exposure_max = 8.0; float tonemap_auto_exposure_speed = 0.5; float tonemap_auto_exposure_grey = 0.4; void _update_tonemap(); @@ -156,7 +156,7 @@ private: float sdfgi_min_cell_size = 0.2; SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED; bool sdfgi_use_occlusion = false; - bool sdfgi_use_multibounce = false; + float sdfgi_bounce_feedback = 0.0; bool sdfgi_read_sky_light = false; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; @@ -196,8 +196,9 @@ private: float volumetric_fog_light_energy = 1.0; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW; float volumetric_fog_gi_inject = 0.0; + bool volumetric_fog_temporal_reproject = true; + float volumetric_fog_temporal_reproject_amount = 0.9; void _update_volumetric_fog(); // Adjustment @@ -317,8 +318,8 @@ public: SDFGIYScale get_sdfgi_y_scale() const; void set_sdfgi_use_occlusion(bool p_enabled); bool is_sdfgi_using_occlusion() const; - void set_sdfgi_use_multi_bounce(bool p_enabled); - bool is_sdfgi_using_multi_bounce() const; + void set_sdfgi_bounce_feedback(float p_amount); + float get_sdfgi_bounce_feedback() const; void set_sdfgi_read_sky_light(bool p_enabled); bool is_sdfgi_reading_sky_light() const; void set_sdfgi_energy(float p_energy); @@ -385,10 +386,12 @@ public: float get_volumetric_fog_length() const; void set_volumetric_fog_detail_spread(float p_detail_spread); float get_volumetric_fog_detail_spread() const; - void set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter); - VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const; void set_volumetric_fog_gi_inject(float p_gi_inject); float get_volumetric_fog_gi_inject() const; + void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable); + bool is_volumetric_fog_temporal_reprojection_enabled() const; + void set_volumetric_fog_temporal_reprojection_amount(float p_amount); + float get_volumetric_fog_temporal_reprojection_amount() const; // Adjustment void set_adjustment_enabled(bool p_enabled); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 1c06d7b519..06a15e36d7 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -177,6 +177,14 @@ void FontData::_get_property_list(List<PropertyInfo> *p_list) const { } } +void FontData::reset_state() { + if (rid != RID()) { + TS->free(rid); + } + base_size = 16; + path = String(); +} + RID FontData::get_rid() const { return rid; } @@ -509,7 +517,7 @@ void Font::_data_changed() { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } bool Font::_set(const StringName &p_name, const Variant &p_value) { @@ -588,6 +596,14 @@ void Font::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::OBJECT, "data/" + itos(data.size()), PROPERTY_HINT_RESOURCE_TYPE, "FontData")); } +void Font::reset_state() { + spacing_top = 0; + spacing_bottom = 0; + cache.clear(); + cache_wrap.clear(); + data.clear(); +} + void Font::add_data(const Ref<FontData> &p_data) { ERR_FAIL_COND(p_data.is_null()); data.push_back(p_data); @@ -600,7 +616,7 @@ void Font::add_data(const Ref<FontData> &p_data) { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void Font::set_data(int p_idx, const Ref<FontData> &p_data) { @@ -621,7 +637,7 @@ void Font::set_data(int p_idx, const Ref<FontData> &p_data) { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } int Font::get_data_count() const { @@ -646,7 +662,7 @@ void Font::remove_data(int p_idx) { cache_wrap.clear(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } Dictionary Font::get_feature_list() const { @@ -718,7 +734,7 @@ void Font::set_spacing(int p_type, int p_value) { } emit_changed(); - _change_notify(); + notify_property_list_changed(); } // Drawing string and string sizes, cached. @@ -951,7 +967,7 @@ Font::~Font() { /*************************************************************************/ -RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } @@ -1006,7 +1022,7 @@ String ResourceFormatLoaderFont::get_resource_type(const String &p_path) const { #ifndef DISABLE_DEPRECATED -RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/scene/resources/font.h b/scene/resources/font.h index 086226c082..a91c9ec7a5 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -53,6 +53,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: virtual RID get_rid() const override; @@ -151,6 +153,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + void _data_changed(); public: @@ -201,7 +205,7 @@ VARIANT_ENUM_CAST(Font::SpacingType); class ResourceFormatLoaderFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; @@ -212,7 +216,7 @@ public: class ResourceFormatLoaderCompatFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp index b87235518f..7b9b942142 100644 --- a/scene/resources/gradient.cpp +++ b/scene/resources/gradient.cpp @@ -39,7 +39,6 @@ Gradient::Gradient() { points.write[0].offset = 0; points.write[1].color = Color(1, 1, 1, 1); points.write[1].offset = 1; - is_sorted = true; } Gradient::~Gradient() { diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h index 344a3fd283..cf5b179c45 100644 --- a/scene/resources/gradient.h +++ b/scene/resources/gradient.h @@ -39,7 +39,7 @@ class Gradient : public Resource { public: struct Point { - float offset; + float offset = 0.0; Color color; bool operator<(const Point &p_ponit) const { return offset < p_ponit.offset; @@ -48,7 +48,7 @@ public: private: Vector<Point> points; - bool is_sorted; + bool is_sorted = true; _FORCE_INLINE_ void _update_sorting() { if (!is_sorted) { points.sort(); diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp index a32cc1c4df..5593bb766f 100644 --- a/scene/resources/height_map_shape_3d.cpp +++ b/scene/resources/height_map_shape_3d.cpp @@ -107,8 +107,6 @@ void HeightMapShape3D::set_map_width(int p_new) { _update_shape(); notify_change_to_owners(); - _change_notify("map_width"); - _change_notify("map_data"); } } @@ -133,8 +131,6 @@ void HeightMapShape3D::set_map_depth(int p_new) { _update_shape(); notify_change_to_owners(); - _change_notify("map_depth"); - _change_notify("map_data"); } } @@ -171,7 +167,6 @@ void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) { _update_shape(); notify_change_to_owners(); - _change_notify("map_data"); } PackedFloat32Array HeightMapShape3D::get_map_data() const { @@ -193,16 +188,12 @@ void HeightMapShape3D::_bind_methods() { HeightMapShape3D::HeightMapShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_HEIGHTMAP)) { - map_width = 2; - map_depth = 2; map_data.resize(map_width * map_depth); real_t *w = map_data.ptrw(); w[0] = 0.0; w[1] = 0.0; w[2] = 0.0; w[3] = 0.0; - min_height = 0.0; - max_height = 0.0; _update_shape(); } diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index eda405fc06..6fc88cff90 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -36,11 +36,11 @@ class HeightMapShape3D : public Shape3D { GDCLASS(HeightMapShape3D, Shape3D); - int map_width; - int map_depth; + int map_width = 2; + int map_depth = 2; PackedFloat32Array map_data; - float min_height; - float max_height; + float min_height = 0.0; + float max_height = 0.0; protected: static void _bind_methods(); diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp index 2b08c21c34..d206f12287 100644 --- a/scene/resources/line_shape_2d.cpp +++ b/scene/resources/line_shape_2d.cpp @@ -113,7 +113,5 @@ void LineShape2D::_bind_methods() { LineShape2D::LineShape2D() : Shape2D(PhysicsServer2D::get_singleton()->line_shape_create()) { - normal = Vector2(0, 1); - distance = 0; _update_shape(); } diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h index 043be1eebe..9f0405ad29 100644 --- a/scene/resources/line_shape_2d.h +++ b/scene/resources/line_shape_2d.h @@ -36,8 +36,8 @@ class LineShape2D : public Shape2D { GDCLASS(LineShape2D, Shape2D); - Vector2 normal; - real_t distance; + Vector2 normal = Vector2(0, 1); + real_t distance = 0.0; void _update_shape(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 445c0d9677..062d921855 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -192,7 +192,7 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) { void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { // Only connect/disconnect the signal when running in the editor. - // This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`) + // This can be a slow operation, and `notify_property_list_changed()` (which is called by `_shader_changed()`) // does nothing in non-editor builds anyway. See GH-34741 for details. if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) { shader->disconnect("changed", callable_mp(this, &ShaderMaterial::_shader_changed)); @@ -210,7 +210,7 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { } RS::get_singleton()->material_set_shader(_get_material(), rid); - _change_notify(); //properties for shader exposed + notify_property_list_changed(); //properties for shader exposed emit_changed(); } @@ -227,7 +227,7 @@ Variant ShaderMaterial::get_shader_param(const StringName &p_param) const { } void ShaderMaterial::_shader_changed() { - _change_notify(); //update all properties + notify_property_list_changed(); //update all properties } void ShaderMaterial::_bind_methods() { @@ -735,7 +735,7 @@ void BaseMaterial3D::_update_shader() { if (flags[FLAG_SRGB_VERTEX_COLOR]) { code += "\tif (!OUTPUT_IS_SRGB) {\n"; - code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n"; + code += "\t\tCOLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n"; code += "\t}\n"; } if (flags[FLAG_USE_POINT_SIZE]) { @@ -1489,7 +1489,7 @@ void BaseMaterial3D::set_transparency(Transparency p_transparency) { transparency = p_transparency; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const { @@ -1503,7 +1503,7 @@ void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) { alpha_antialiasing_mode = p_alpha_aa; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::AlphaAntiAliasing BaseMaterial3D::get_alpha_antialiasing() const { @@ -1517,7 +1517,7 @@ void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) { shading_mode = p_shading_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const { @@ -1585,7 +1585,7 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { flags[p_flag] = p_enabled; if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) { - _change_notify(); + notify_property_list_changed(); } _queue_shader_change(); } @@ -1602,7 +1602,7 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) { } features[p_feature] = p_enabled; - _change_notify(); + notify_property_list_changed(); _queue_shader_change(); } @@ -1620,7 +1620,7 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size, Vector2i(p_texture->get_width(), p_texture->get_height())); } - _change_notify(); + notify_property_list_changed(); _queue_shader_change(); } @@ -1860,7 +1860,7 @@ float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const { void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) { billboard_mode = p_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const { @@ -1897,7 +1897,7 @@ bool BaseMaterial3D::get_particles_anim_loop() const { void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) { deep_parallax = p_enable; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const { @@ -1943,7 +1943,7 @@ bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const { void BaseMaterial3D::set_grow_enabled(bool p_enable) { grow_enabled = p_enable; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool BaseMaterial3D::is_grow_enabled() const { @@ -2093,7 +2093,7 @@ void BaseMaterial3D::set_on_top_of_alpha() { void BaseMaterial3D::set_proximity_fade(bool p_enable) { proximity_fade_enabled = p_enable; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } bool BaseMaterial3D::is_proximity_fade_enabled() const { @@ -2112,7 +2112,7 @@ float BaseMaterial3D::get_proximity_fade_distance() const { void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) { distance_fade = p_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const { @@ -2655,9 +2655,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : element(this) { orm = p_orm; // Initialize to the same values as the shader - shading_mode = SHADING_MODE_PER_PIXEL; - transparency = TRANSPARENCY_DISABLED; - alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; set_albedo(Color(1.0, 1.0, 1.0, 1.0)); set_specular(0.5); set_roughness(1.0); @@ -2689,7 +2686,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_particles_anim_h_frames(1); set_particles_anim_v_frames(1); set_particles_anim_loop(false); - emission_op = EMISSION_OP_ADD; set_transparency(TRANSPARENCY_DISABLED); set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF); @@ -2697,8 +2693,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_alpha_hash_scale(1.0); set_alpha_antialiasing_edge(0.3); - proximity_fade_enabled = false; - distance_fade = DISTANCE_FADE_DISABLED; set_proximity_fade_distance(1); set_distance_fade_min_distance(0); set_distance_fade_max_distance(10); @@ -2710,35 +2704,14 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_ao_texture_channel(TEXTURE_CHANNEL_RED); set_refraction_texture_channel(TEXTURE_CHANNEL_RED); - grow_enabled = false; set_grow(0.0); - deep_parallax = false; - heightmap_parallax_flip_tangent = false; - heightmap_parallax_flip_binormal = false; set_heightmap_deep_parallax_min_layers(8); set_heightmap_deep_parallax_max_layers(32); set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal - detail_uv = DETAIL_UV_1; - blend_mode = BLEND_MODE_MIX; - detail_blend_mode = BLEND_MODE_MIX; - depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY; - cull_mode = CULL_BACK; - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; - } flags[FLAG_USE_TEXTURE_REPEAT] = true; - diffuse_mode = DIFFUSE_BURLEY; - specular_mode = SPECULAR_SCHLICK_GGX; - - for (int i = 0; i < FEATURE_MAX; i++) { - features[i] = false; - } - - texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; - _queue_shader_change(); } diff --git a/scene/resources/material.h b/scene/resources/material.h index 0048b43c8b..595db36a57 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -330,7 +330,7 @@ private: struct ShaderData { RID shader; - int users; + int users = 0; }; static Map<MaterialKey, ShaderData> shader_map; @@ -468,16 +468,16 @@ private: float alpha_scissor_threshold; float alpha_hash_scale; float alpha_antialiasing_edge; - bool grow_enabled; + bool grow_enabled = false; float ao_light_affect; float grow; int particles_anim_h_frames; int particles_anim_v_frames; bool particles_anim_loop; - Transparency transparency; - ShadingMode shading_mode; + Transparency transparency = TRANSPARENCY_DISABLED; + ShadingMode shading_mode = SHADING_MODE_PER_PIXEL; - TextureFilter texture_filter; + TextureFilter texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; Vector3 uv1_scale; Vector3 uv1_offset; @@ -487,37 +487,37 @@ private: Vector3 uv2_offset; float uv2_triplanar_sharpness; - DetailUV detail_uv; + DetailUV detail_uv = DETAIL_UV_1; - bool deep_parallax; + bool deep_parallax = false; int deep_parallax_min_layers; int deep_parallax_max_layers; - bool heightmap_parallax_flip_tangent; - bool heightmap_parallax_flip_binormal; + bool heightmap_parallax_flip_tangent = false; + bool heightmap_parallax_flip_binormal = false; - bool proximity_fade_enabled; + bool proximity_fade_enabled = false; float proximity_fade_distance; - DistanceFadeMode distance_fade; + DistanceFadeMode distance_fade = DISTANCE_FADE_DISABLED; float distance_fade_max_distance; float distance_fade_min_distance; - BlendMode blend_mode; - BlendMode detail_blend_mode; - DepthDrawMode depth_draw_mode; - CullMode cull_mode; - bool flags[FLAG_MAX]; - SpecularMode specular_mode; - DiffuseMode diffuse_mode; + BlendMode blend_mode = BLEND_MODE_MIX; + BlendMode detail_blend_mode = BLEND_MODE_MIX; + DepthDrawMode depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY; + CullMode cull_mode = CULL_BACK; + bool flags[FLAG_MAX] = {}; + SpecularMode specular_mode = SPECULAR_SCHLICK_GGX; + DiffuseMode diffuse_mode = DIFFUSE_BURLEY; BillboardMode billboard_mode; - EmissionOperator emission_op; + EmissionOperator emission_op = EMISSION_OP_ADD; TextureChannel metallic_texture_channel; TextureChannel roughness_texture_channel; TextureChannel ao_texture_channel; TextureChannel refraction_texture_channel; - AlphaAntiAliasing alpha_antialiasing_mode; + AlphaAntiAliasing alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; bool features[FEATURE_MAX]; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index e812ad3a01..1a2b21299a 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1095,6 +1095,15 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { return true; } +void ArrayMesh::reset_state() { + clear_surfaces(); + clear_blend_shapes(); + + aabb = AABB(); + blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; + custom_aabb = AABB(); +} + void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { if (_is_generated()) { return; @@ -1156,7 +1165,7 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const RenderingServer::get_singleton()->mesh_add_surface(mesh, sd); clear_cache(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -1278,7 +1287,6 @@ void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) surfaces.write[p_idx].material = p_material; RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid()); - _change_notify("material"); emit_changed(); } @@ -1375,8 +1383,8 @@ bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_v struct ArrayMeshLightmapSurface { Ref<Material> material; LocalVector<SurfaceTool::Vertex> vertices; - Mesh::PrimitiveType primitive; - uint32_t format; + Mesh::PrimitiveType primitive = Mesh::PrimitiveType::PRIMITIVE_MAX; + uint32_t format = 0; }; Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { @@ -1633,13 +1641,12 @@ void ArrayMesh::reload_from_file() { Resource::reload_from_file(); - _change_notify(); + notify_property_list_changed(); } ArrayMesh::ArrayMesh() { //mesh is now created on demand //mesh = RenderingServer::get_singleton()->mesh_create(); - blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; } ArrayMesh::~ArrayMesh() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 1fd45c880a..2ce519e644 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -180,20 +180,20 @@ class ArrayMesh : public Mesh { private: struct Surface { - uint32_t format; - int array_length; - int index_array_length; - PrimitiveType primitive; + uint32_t format = 0; + int array_length = 0; + int index_array_length = 0; + PrimitiveType primitive = PrimitiveType::PRIMITIVE_MAX; String name; AABB aabb; Ref<Material> material; - bool is_2d; + bool is_2d = false; }; Vector<Surface> surfaces; mutable RID mesh; AABB aabb; - BlendShapeMode blend_shape_mode; + BlendShapeMode blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; Vector<StringName> blend_shapes; AABB custom_aabb; @@ -207,6 +207,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + static void _bind_methods(); public: diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h index d8b8d85900..f5c8f11437 100644 --- a/scene/resources/mesh_data_tool.h +++ b/scene/resources/mesh_data_tool.h @@ -36,7 +36,7 @@ class MeshDataTool : public Reference { GDCLASS(MeshDataTool, Reference); - int format; + int format = 0; struct Vertex { Vector3 vertex; Color color; @@ -54,7 +54,7 @@ class MeshDataTool : public Reference { Vector<Vertex> vertices; struct Edge { - int vertex[2]; + int vertex[2] = {}; Vector<int> faces; Variant meta; }; @@ -62,8 +62,8 @@ class MeshDataTool : public Reference { Vector<Edge> edges; struct Face { - int v[3]; - int edges[3]; + int v[3] = {}; + int edges[3] = {}; Variant meta; }; diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index 96d3a5750e..ad90481fbd 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -109,14 +109,14 @@ void MeshLibrary::create_item(int p_item) { ERR_FAIL_COND(p_item < 0); ERR_FAIL_COND(item_map.has(p_item)); item_map[p_item] = Item(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_name(int p_item, const String &p_name) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].name = p_name; emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) { @@ -124,25 +124,25 @@ void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) { item_map[p_item].mesh = p_mesh; notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].shapes = p_shapes; - _change_notify(); + notify_property_list_changed(); notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].navmesh = p_navmesh; - _change_notify(); + notify_property_list_changed(); notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) { @@ -150,14 +150,14 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran item_map[p_item].navmesh_transform = p_transform; notify_change_to_owners(); emit_changed(); - _change_notify(); + notify_property_list_changed(); } void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].preview = p_preview; emit_changed(); - _change_notify(); + notify_property_list_changed(); } String MeshLibrary::get_item_name(int p_item) const { @@ -198,14 +198,14 @@ void MeshLibrary::remove_item(int p_item) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map.erase(p_item); notify_change_to_owners(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } void MeshLibrary::clear() { item_map.clear(); notify_change_to_owners(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -264,6 +264,9 @@ Array MeshLibrary::_get_item_shapes(int p_item) const { return ret; } +void MeshLibrary::reset_state() { + clear(); +} void MeshLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("create_item", "id"), &MeshLibrary::create_item); ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 5c302fcf08..1da624c275 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -65,6 +65,7 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; static void _bind_methods(); public: diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 050e398ca4..4991887eb3 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -217,7 +217,7 @@ Ref<Mesh> MultiMesh::get_mesh() const { void MultiMesh::set_instance_count(int p_count) { ERR_FAIL_COND(p_count < 0); - RenderingServer::get_singleton()->multimesh_allocate(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data); + RenderingServer::get_singleton()->multimesh_allocate_data(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data); instance_count = p_count; } @@ -361,11 +361,6 @@ void MultiMesh::_bind_methods() { MultiMesh::MultiMesh() { multimesh = RenderingServer::get_singleton()->multimesh_create(); - use_colors = false; - use_custom_data = false; - transform_format = TRANSFORM_2D; - visible_instance_count = -1; - instance_count = 0; } MultiMesh::~MultiMesh() { diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 633d754b8e..ca5c42d47a 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -47,11 +47,11 @@ public: private: Ref<Mesh> mesh; RID multimesh; - TransformFormat transform_format; - bool use_colors; - bool use_custom_data; - int instance_count; - int visible_instance_count; + TransformFormat transform_format = TRANSFORM_2D; + bool use_colors = false; + bool use_custom_data = false; + int instance_count = 0; + int visible_instance_count = -1; protected: static void _bind_methods(); diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 43c3ef4edc..84f3c23f77 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -74,7 +74,7 @@ int NavigationMesh::get_sample_partition_type() const { void NavigationMesh::set_parsed_geometry_type(int p_value) { ERR_FAIL_COND(p_value >= PARSED_GEOMETRY_MAX); parsed_geometry_type = static_cast<ParsedGeometryType>(p_value); - _change_notify(); + notify_property_list_changed(); } int NavigationMesh::get_parsed_geometry_type() const { @@ -106,7 +106,7 @@ bool NavigationMesh::get_collision_mask_bit(int p_bit) const { void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) { ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX); source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode); - _change_notify(); + notify_property_list_changed(); } int NavigationMesh::get_source_geometry_mode() const { @@ -251,7 +251,7 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const { void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) { vertices = p_vertices; - _change_notify(); + notify_property_list_changed(); } Vector<Vector3> NavigationMesh::get_vertices() const { @@ -263,7 +263,7 @@ void NavigationMesh::_set_polygons(const Array &p_array) { for (int i = 0; i < p_array.size(); i++) { polygons.write[i].indices = p_array[i]; } - _change_notify(); + notify_property_list_changed(); } Array NavigationMesh::_get_polygons() const { @@ -280,7 +280,7 @@ void NavigationMesh::add_polygon(const Vector<int> &p_polygon) { Polygon polygon; polygon.indices = p_polygon; polygons.push_back(polygon); - _change_notify(); + notify_property_list_changed(); } int NavigationMesh::get_polygon_count() const { @@ -510,27 +510,4 @@ void NavigationMesh::_validate_property(PropertyInfo &property) const { } } -NavigationMesh::NavigationMesh() { - cell_size = 0.3f; - cell_height = 0.2f; - agent_height = 2.0f; - agent_radius = 0.6f; - agent_max_climb = 0.9f; - agent_max_slope = 45.0f; - region_min_size = 8.0f; - region_merge_size = 20.0f; - edge_max_length = 12.0f; - edge_max_error = 1.3f; - verts_per_poly = 6.0f; - detail_sample_distance = 6.0f; - detail_sample_max_error = 1.0f; - - partition_type = SAMPLE_PARTITION_WATERSHED; - parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES; - collision_mask = 0xFFFFFFFF; - source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN; - source_group_name = "navmesh"; - filter_low_hanging_obstacles = false; - filter_ledge_spans = false; - filter_walkable_low_height_spans = false; -} +NavigationMesh::NavigationMesh() {} diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 693c4184bc..966221c7c6 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -82,30 +82,30 @@ public: }; protected: - float cell_size; - float cell_height; - float agent_height; - float agent_radius; - float agent_max_climb; - float agent_max_slope; - float region_min_size; - float region_merge_size; - float edge_max_length; - float edge_max_error; - float verts_per_poly; - float detail_sample_distance; - float detail_sample_max_error; - - SamplePartitionType partition_type; - ParsedGeometryType parsed_geometry_type; - uint32_t collision_mask; - - SourceGeometryMode source_geometry_mode; - StringName source_group_name; - - bool filter_low_hanging_obstacles; - bool filter_ledge_spans; - bool filter_walkable_low_height_spans; + float cell_size = 0.3f; + float cell_height = 0.2f; + float agent_height = 2.0f; + float agent_radius = 0.6f; + float agent_max_climb = 0.9f; + float agent_max_slope = 45.0f; + float region_min_size = 8.0f; + float region_merge_size = 20.0f; + float edge_max_length = 12.0f; + float edge_max_error = 1.3f; + float verts_per_poly = 6.0f; + float detail_sample_distance = 6.0f; + float detail_sample_max_error = 1.0f; + + SamplePartitionType partition_type = SAMPLE_PARTITION_WATERSHED; + ParsedGeometryType parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES; + uint32_t collision_mask = 0xFFFFFFFF; + + SourceGeometryMode source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN; + StringName source_group_name = "navmesh"; + + bool filter_low_hanging_obstacles = false; + bool filter_ledge_spans = false; + bool filter_walkable_low_height_spans = false; public: // Recast settings diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 794b281100..beb365d44e 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -1589,8 +1589,6 @@ void SceneState::_bind_methods() { } SceneState::SceneState() { - base_scene_idx = -1; - last_modified_time = 0; } //////////////// @@ -1663,6 +1661,9 @@ void PackedScene::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); } +void PackedScene::reset_state() { + clear(); +} void PackedScene::_bind_methods() { ClassDB::bind_method(D_METHOD("pack", "path"), &PackedScene::pack); ClassDB::bind_method(D_METHOD("instance", "edit_state"), &PackedScene::instance, DEFVAL(GEN_EDIT_STATE_DISABLED)); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index a31dcd8d39..78a0aeaa9a 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -44,7 +44,7 @@ class SceneState : public Reference { mutable HashMap<NodePath, int> node_path_cache; mutable Map<int, int> base_scene_node_remap; - int base_scene_idx; + int base_scene_idx = -1; enum { NO_PARENT_SAVED = 0x7FFFFFFF, @@ -53,16 +53,16 @@ class SceneState : public Reference { }; struct NodeData { - int parent; - int owner; - int type; - int name; - int instance; - int index; + int parent = 0; + int owner = 0; + int type = 0; + int name = 0; + int instance = 0; + int index = 0; struct Property { - int name; - int value; + int name = 0; + int value = 0; }; Vector<Property> properties; @@ -71,18 +71,17 @@ class SceneState : public Reference { struct PackState { Ref<SceneState> state; - int node; - PackState() { node = -1; } + int node = -1; }; Vector<NodeData> nodes; struct ConnectionData { - int from; - int to; - int signal; - int method; - int flags; + int from = 0; + int to = 0; + int signal = 0; + int method = 0; + int flags = 0; Vector<int> binds; }; @@ -93,7 +92,7 @@ class SceneState : public Reference { String path; - uint64_t last_modified_time; + uint64_t last_modified_time = 0; _FORCE_INLINE_ Ref<SceneState> _get_base_scene_state() const; @@ -201,6 +200,7 @@ class PackedScene : public Resource { protected: virtual bool editor_can_reload_from_file() override { return false; } // this is handled by editor better static void _bind_methods(); + virtual void reset_state() override; public: enum GenEditState { diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 3aa9f9b3bc..167540eb77 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -305,6 +305,7 @@ void ParticlesMaterial::_update_shader() { code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n"; code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n"; } + code += " float tv = 0.0;\n"; code += " if (RESTART) {\n"; if (tex_parameters[PARAM_ANGLE].is_valid()) { @@ -407,64 +408,65 @@ void ParticlesMaterial::_update_shader() { code += " } else {\n"; code += " CUSTOM.y += DELTA / LIFETIME;\n"; + code += " tv = CUSTOM.y / CUSTOM.w;\n"; if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_linear_velocity = 0.0;\n"; } if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_orbit_velocity = 0.0;\n"; } } if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) { - code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_angular_velocity = 0.0;\n"; } if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) { - code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_linear_accel = 0.0;\n"; } if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) { - code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_radial_accel = 0.0;\n"; } if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) { - code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_tangent_accel = 0.0;\n"; } if (tex_parameters[PARAM_DAMPING].is_valid()) { - code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_damping = textureLod(damping_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_damping = 0.0;\n"; } if (tex_parameters[PARAM_ANGLE].is_valid()) { - code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_angle = textureLod(angle_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_angle = 0.0;\n"; } if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) { - code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_anim_speed = 0.0;\n"; } if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) { - code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_anim_offset = 0.0;\n"; } @@ -526,13 +528,13 @@ void ParticlesMaterial::_update_shader() { // apply color // apply hue rotation if (tex_parameters[PARAM_SCALE].is_valid()) { - code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_scale = 1.0;\n"; } if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) { - code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(tv, 0.0), 0.0).r;\n"; } else { code += " float tex_hue_variation = 0.0;\n"; } @@ -553,7 +555,7 @@ void ParticlesMaterial::_update_shader() { code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; if (color_ramp.is_valid()) { - code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(CUSTOM.y, 0.0), 0.0);\n"; + code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n"; } else { code += " COLOR = hue_rot_mat * color_value;\n"; } @@ -909,7 +911,7 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { color_ramp = p_texture; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture); _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { @@ -921,7 +923,7 @@ void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_ particle_flags[p_particle_flag] = p_enable; _queue_shader_change(); if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { - _change_notify(); + notify_property_list_changed(); } } @@ -933,7 +935,7 @@ bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; - _change_notify(); + notify_property_list_changed(); _queue_shader_change(); } @@ -1064,7 +1066,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { sub_emitter_mode = p_sub_emitter_mode; _queue_shader_change(); - _change_notify(); + notify_property_list_changed(); } ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const { @@ -1368,7 +1370,6 @@ ParticlesMaterial::ParticlesMaterial() : set_emission_box_extents(Vector3(1, 1, 1)); set_gravity(Vector3(0, -9.8, 0)); set_lifetime_randomness(0); - emission_point_count = 1; set_sub_emitter_mode(SUB_EMITTER_DISABLED); set_sub_emitter_frequency(4); @@ -1391,7 +1392,6 @@ ParticlesMaterial::ParticlesMaterial() : set_color(Color(1, 1, 1, 1)); - current_key.key = 0; current_key.invalid_key = 1; _queue_shader_change(); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 49b48a01b7..3f874bd68c 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -100,7 +100,7 @@ private: uint32_t collision_scale : 1; }; - uint32_t key; + uint32_t key = 0; bool operator<(const MaterialKey &p_key) const { return key < p_key.key; @@ -109,7 +109,7 @@ private: struct ShaderData { RID shader; - int users; + int users = 0; }; static Map<MaterialKey, ShaderData> shader_map; @@ -235,7 +235,7 @@ private: Ref<Texture2D> emission_point_texture; Ref<Texture2D> emission_normal_texture; Ref<Texture2D> emission_color_texture; - int emission_point_count; + int emission_point_count = 1; bool anim_loop; diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h index dfb2d1480b..d302800823 100644 --- a/scene/resources/physics_material.h +++ b/scene/resources/physics_material.h @@ -39,9 +39,9 @@ class PhysicsMaterial : public Resource { OBJ_SAVE_TYPE(PhysicsMaterial); RES_BASE_EXTENSION("phymat"); - real_t friction = 1; + real_t friction = 1.0; bool rough = false; - real_t bounce = 0; + real_t bounce = 0.0; bool absorbent = false; protected: diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index 410e1dba52..2f3cb634fb 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -39,13 +39,13 @@ class PolygonPathFinder : public Resource { struct Point { Vector2 pos; Set<int> connections; - float distance; - float penalty; - int prev; + float distance = 0.0; + float penalty = 0.0; + int prev = 0; }; struct Edge { - int points[2]; + int points[2] = {}; _FORCE_INLINE_ bool operator<(const Edge &p_edge) const { if (points[0] == p_edge.points[0]) { diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index a6e9e7b5d2..ba6c4591c9 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -214,7 +214,7 @@ void PrimitiveMesh::set_material(const Ref<Material> &p_material) { if (!pending_request) { // just apply it, else it'll happen when _update is called. RenderingServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); - _change_notify(); + notify_property_list_changed(); emit_changed(); }; } @@ -247,18 +247,7 @@ bool PrimitiveMesh::get_flip_faces() const { } PrimitiveMesh::PrimitiveMesh() { - flip_faces = false; - // defaults mesh = RenderingServer::get_singleton()->mesh_create(); - - // assume primitive triangles as the type, correct for all but one and it will change this :) - primitive_type = Mesh::PRIMITIVE_TRIANGLES; - - // make sure we do an update after we've finished constructing our object - pending_request = true; - - array_len = 0; - index_array_len = 0; } PrimitiveMesh::~PrimitiveMesh() { @@ -304,8 +293,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { u = i; u /= radial_segments; - x = -sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = -sin(u * Math_TAU); + z = cos(u * Math_TAU); Vector3 p = Vector3(x * radius * w, y, -z * radius * w); points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0)); @@ -343,8 +332,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { u = i; u /= radial_segments; - x = -sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = -sin(u * Math_TAU); + z = cos(u * Math_TAU); Vector3 p = Vector3(x * radius, y, -z * radius); points.push_back(p); @@ -383,8 +372,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { float u2 = i; u2 /= radial_segments; - x = -sin(u2 * (Math_PI * 2.0)); - z = cos(u2 * (Math_PI * 2.0)); + x = -sin(u2 * Math_TAU); + z = cos(u2 * Math_TAU); Vector3 p = Vector3(x * radius * w, y, -z * radius * w); points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0)); @@ -468,13 +457,7 @@ int CapsuleMesh::get_rings() const { return rings; } -CapsuleMesh::CapsuleMesh() { - // defaults - radius = 1.0; - mid_height = 1.0; - radial_segments = 64; - rings = 8; -} +CapsuleMesh::CapsuleMesh() {} /** BoxMesh @@ -725,13 +708,7 @@ int BoxMesh::get_subdivide_depth() const { return subdivide_d; } -BoxMesh::BoxMesh() { - // defaults - size = Vector3(2.0, 2.0, 2.0); - subdivide_w = 0; - subdivide_h = 0; - subdivide_d = 0; -} +BoxMesh::BoxMesh() {} /** CylinderMesh @@ -769,8 +746,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { u = i; u /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = sin(u * Math_TAU); + z = cos(u * Math_TAU); Vector3 p = Vector3(x * radius, y, z * radius); points.push_back(p); @@ -809,8 +786,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { float r = i; r /= radial_segments; - x = sin(r * (Math_PI * 2.0)); - z = cos(r * (Math_PI * 2.0)); + x = sin(r * Math_TAU); + z = cos(r * Math_TAU); u = ((x + 1.0) * 0.25); v = 0.5 + ((z + 1.0) * 0.25); @@ -845,8 +822,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { float r = i; r /= radial_segments; - x = sin(r * (Math_PI * 2.0)); - z = cos(r * (Math_PI * 2.0)); + x = sin(r * Math_TAU); + z = cos(r * Math_TAU); u = 0.5 + ((x + 1.0) * 0.25); v = 1.0 - ((z + 1.0) * 0.25); @@ -938,14 +915,7 @@ int CylinderMesh::get_rings() const { return rings; } -CylinderMesh::CylinderMesh() { - // defaults - top_radius = 1.0; - bottom_radius = 1.0; - height = 2.0; - radial_segments = 64; - rings = 4; -} +CylinderMesh::CylinderMesh() {} /** PlaneMesh @@ -1053,12 +1023,7 @@ int PlaneMesh::get_subdivide_depth() const { return subdivide_d; } -PlaneMesh::PlaneMesh() { - // defaults - size = Size2(2.0, 2.0); - subdivide_w = 0; - subdivide_d = 0; -} +PlaneMesh::PlaneMesh() {} /** PrismMesh @@ -1338,14 +1303,7 @@ int PrismMesh::get_subdivide_depth() const { return subdivide_d; } -PrismMesh::PrismMesh() { - // defaults - left_to_right = 0.5; - size = Vector3(2.0, 2.0, 2.0); - subdivide_w = 0; - subdivide_h = 0; - subdivide_d = 0; -} +PrismMesh::PrismMesh() {} /** QuadMesh @@ -1409,7 +1367,6 @@ void QuadMesh::_bind_methods() { QuadMesh::QuadMesh() { primitive_type = PRIMITIVE_TRIANGLES; - size = Size2(1.0, 1.0); } void QuadMesh::set_size(const Size2 &p_size) { @@ -1458,8 +1415,8 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const { float u = i; u /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - z = cos(u * (Math_PI * 2.0)); + x = sin(u * Math_TAU); + z = cos(u * Math_TAU); if (is_hemisphere && y < 0.0) { points.push_back(Vector3(x * radius * w, 0.0, z * radius * w)); @@ -1561,14 +1518,7 @@ bool SphereMesh::get_is_hemisphere() const { return is_hemisphere; } -SphereMesh::SphereMesh() { - // defaults - radius = 1.0; - height = 2.0; - radial_segments = 64; - rings = 32; - is_hemisphere = false; -} +SphereMesh::SphereMesh() {} /** PointMesh diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index d0ca4b10e7..bb3df9d10e 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -49,17 +49,19 @@ private: mutable AABB aabb; AABB custom_aabb; - mutable int array_len; - mutable int index_array_len; + mutable int array_len = 0; + mutable int index_array_len = 0; Ref<Material> material; - bool flip_faces; + bool flip_faces = false; - mutable bool pending_request; + // make sure we do an update after we've finished constructing our object + mutable bool pending_request = true; void _update() const; protected: - Mesh::PrimitiveType primitive_type; + // assume primitive triangles as the type, correct for all but one and it will change this :) + Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES; static void _bind_methods(); @@ -104,10 +106,10 @@ class CapsuleMesh : public PrimitiveMesh { GDCLASS(CapsuleMesh, PrimitiveMesh); private: - float radius; - float mid_height; - int radial_segments; - int rings; + float radius = 1.0; + float mid_height = 1.0; + int radial_segments = 64; + int rings = 8; protected: static void _bind_methods(); @@ -136,10 +138,10 @@ class BoxMesh : public PrimitiveMesh { GDCLASS(BoxMesh, PrimitiveMesh); private: - Vector3 size; - int subdivide_w; - int subdivide_h; - int subdivide_d; + Vector3 size = Vector3(2.0, 2.0, 2.0); + int subdivide_w = 0; + int subdivide_h = 0; + int subdivide_d = 0; protected: static void _bind_methods(); @@ -169,11 +171,11 @@ class CylinderMesh : public PrimitiveMesh { GDCLASS(CylinderMesh, PrimitiveMesh); private: - float top_radius; - float bottom_radius; - float height; - int radial_segments; - int rings; + float top_radius = 1.0; + float bottom_radius = 1.0; + float height = 2.0; + int radial_segments = 64; + int rings = 4; protected: static void _bind_methods(); @@ -205,9 +207,9 @@ class PlaneMesh : public PrimitiveMesh { GDCLASS(PlaneMesh, PrimitiveMesh); private: - Size2 size; - int subdivide_w; - int subdivide_d; + Size2 size = Size2(2.0, 2.0); + int subdivide_w = 0; + int subdivide_d = 0; protected: static void _bind_methods(); @@ -233,11 +235,11 @@ class PrismMesh : public PrimitiveMesh { GDCLASS(PrismMesh, PrimitiveMesh); private: - float left_to_right; - Vector3 size; - int subdivide_w; - int subdivide_h; - int subdivide_d; + float left_to_right = 0.5; + Vector3 size = Vector3(2.0, 2.0, 2.0); + int subdivide_w = 0; + int subdivide_h = 0; + int subdivide_d = 0; protected: static void _bind_methods(); @@ -270,7 +272,7 @@ class QuadMesh : public PrimitiveMesh { GDCLASS(QuadMesh, PrimitiveMesh); private: - Size2 size; + Size2 size = Size2(1.0, 1.0); protected: static void _bind_methods(); @@ -290,11 +292,11 @@ class SphereMesh : public PrimitiveMesh { GDCLASS(SphereMesh, PrimitiveMesh); private: - float radius; - float height; - int radial_segments; - int rings; - bool is_hemisphere; + float radius = 1.0; + float height = 2.0; + int radial_segments = 64; + int rings = 32; + bool is_hemisphere = false; protected: static void _bind_methods(); diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp index 98fd160810..d2125445fa 100644 --- a/scene/resources/ray_shape_2d.cpp +++ b/scene/resources/ray_shape_2d.cpp @@ -45,7 +45,7 @@ void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector2 tip = Vector2(0, get_length()); RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3); Vector<Vector2> pts; - float tsize = 4; + float tsize = 4.0; pts.push_back(tip + Vector2(0, tsize)); pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0)); pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0)); @@ -99,7 +99,5 @@ bool RayShape2D::get_slips_on_slope() const { RayShape2D::RayShape2D() : Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) { - length = 20; - slips_on_slope = false; _update_shape(); } diff --git a/scene/resources/ray_shape_2d.h b/scene/resources/ray_shape_2d.h index 3570b7be52..56ecfa2722 100644 --- a/scene/resources/ray_shape_2d.h +++ b/scene/resources/ray_shape_2d.h @@ -36,8 +36,8 @@ class RayShape2D : public Shape2D { GDCLASS(RayShape2D, Shape2D); - real_t length; - bool slips_on_slope; + real_t length = 20.0; + bool slips_on_slope = false; void _update_shape(); diff --git a/scene/resources/ray_shape_3d.cpp b/scene/resources/ray_shape_3d.cpp index a332bb575f..5446b4daab 100644 --- a/scene/resources/ray_shape_3d.cpp +++ b/scene/resources/ray_shape_3d.cpp @@ -56,7 +56,6 @@ void RayShape3D::set_length(float p_length) { length = p_length; _update_shape(); notify_change_to_owners(); - _change_notify("length"); } float RayShape3D::get_length() const { @@ -67,7 +66,6 @@ void RayShape3D::set_slips_on_slope(bool p_active) { slips_on_slope = p_active; _update_shape(); notify_change_to_owners(); - _change_notify("slips_on_slope"); } bool RayShape3D::get_slips_on_slope() const { @@ -87,12 +85,7 @@ void RayShape3D::_bind_methods() { RayShape3D::RayShape3D() : Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_RAY)) { - length = 1.0; - slips_on_slope = false; - /* Code copied from setters to prevent the use of uninitialized variables */ _update_shape(); notify_change_to_owners(); - _change_notify("length"); - _change_notify("slips_on_slope"); } diff --git a/scene/resources/ray_shape_3d.h b/scene/resources/ray_shape_3d.h index 2c27d56c63..2da6311321 100644 --- a/scene/resources/ray_shape_3d.h +++ b/scene/resources/ray_shape_3d.h @@ -34,8 +34,8 @@ class RayShape3D : public Shape3D { GDCLASS(RayShape3D, Shape3D); - float length; - bool slips_on_slope; + float length = 1.0; + bool slips_on_slope = false; protected: static void _bind_methods(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 433e3392e3..7ca532e1d6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -114,23 +114,8 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R } int index = token.value; - - if (use_nocache) { - r_res = int_resources[index]; - } else { - String path = local_path + "::" + itos(index); - - if (!ignore_resource_parsing) { - if (!ResourceCache::has(path)) { - r_err_str = "Can't load cached sub-resource: " + path; - return ERR_PARSE_ERROR; - } - - r_res = RES(ResourceCache::get(path)); - } else { - r_res = RES(); - } - } + ERR_FAIL_COND_V(!int_resources.has(index), ERR_INVALID_PARAMETER); + r_res = int_resources[index]; VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -440,7 +425,7 @@ Error ResourceLoaderText::load() { er.type = type; if (use_sub_threads) { - Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, local_path); + Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, ResourceFormatLoader::CACHE_MODE_REUSE, local_path); if (err != OK) { if (ResourceLoader::get_abort_on_missing_resources()) { @@ -517,29 +502,44 @@ Error ResourceLoaderText::load() { //bool exists=ResourceCache::has(path); Ref<Resource> res; + bool do_assign = false; - if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist - - Object *obj = ClassDB::instance(type); - if (!obj) { - error_text += "Can't create sub resource of type: " + type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) { + //reuse existing + Resource *r = ResourceCache::get(path); + if (r && r->get_class() == type) { + res = Ref<Resource>(r); + res->reset_state(); + do_assign = true; } + } - Resource *r = Object::cast_to<Resource>(obj); - if (!r) { - error_text += "Can't create sub resource of type, because not a resource: " + type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } + if (res.is_null()) { //not reuse + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && ResourceCache::has(path)) { //only if it doesn't exist + //cached, do not assign + Resource *r = ResourceCache::get(path); + res = Ref<Resource>(r); + } else { + //create - res = Ref<Resource>(r); - int_resources[id] = res; - if (!use_nocache) { - res->set_path(path); + Object *obj = ClassDB::instance(type); + if (!obj) { + error_text += "Can't create sub resource of type: " + type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + Resource *r = Object::cast_to<Resource>(obj); + if (!r) { + error_text += "Can't create sub resource of type, because not a resource: " + type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + res = Ref<Resource>(r); + do_assign = true; } } @@ -557,7 +557,7 @@ Error ResourceLoaderText::load() { } if (assign != String()) { - if (res.is_valid()) { + if (do_assign) { res->set(assign, value); } //it's assignment @@ -572,6 +572,11 @@ Error ResourceLoaderText::load() { } } + int_resources[id] = res; //always assign int resources + if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { + res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); + } + if (progress && resources_total > 0) { *progress = resource_current / float(resources_total); } @@ -589,23 +594,33 @@ Error ResourceLoaderText::load() { return error; } - Object *obj = ClassDB::instance(res_type); - if (!obj) { - error_text += "Can't create sub resource of type: " + res_type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; + if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(local_path)) { + Resource *r = ResourceCache::get(local_path); + if (r->get_class() == res_type) { + r->reset_state(); + resource = Ref<Resource>(r); + } } - Resource *r = Object::cast_to<Resource>(obj); - if (!r) { - error_text += "Can't create sub resource of type, because not a resource: " + res_type; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } + if (!resource.is_valid()) { + Object *obj = ClassDB::instance(res_type); + if (!obj) { + error_text += "Can't create sub resource of type: " + res_type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + Resource *r = Object::cast_to<Resource>(obj); + if (!r) { + error_text += "Can't create sub resource of type, because not a resource: " + res_type; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } - resource = Ref<Resource>(r); + resource = Ref<Resource>(r); + } resource_current++; @@ -620,7 +635,7 @@ Error ResourceLoaderText::load() { _printerr(); } else { error = OK; - if (!use_nocache) { + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { if (!ResourceCache::has(res_path)) { resource->set_path(res_path); } @@ -668,7 +683,7 @@ Error ResourceLoaderText::load() { error = OK; //get it here resource = packed_scene; - if (!use_nocache && !ResourceCache::has(res_path)) { + if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && !ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } @@ -699,18 +714,7 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) { translation_remapped = p_remapped; } -ResourceLoaderText::ResourceLoaderText() { - use_nocache = false; - - resources_total = 0; - resource_current = 0; - - progress = nullptr; - lines = false; - translation_remapped = false; - use_sub_threads = false; - error = OK; -} +ResourceLoaderText::ResourceLoaderText() {} ResourceLoaderText::~ResourceLoaderText() { memdelete(f); @@ -1252,7 +1256,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) { ///////////////////// -RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; } @@ -1265,7 +1269,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina ResourceLoaderText loader; String path = p_original_path != "" ? p_original_path : p_path; - loader.use_nocache = p_no_cache; + loader.cache_mode = p_cache_mode; loader.use_sub_threads = p_use_sub_threads; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.progress = r_progress; diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index e67a13d41a..2dc683415d 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -38,12 +38,12 @@ #include "scene/resources/packed_scene.h" class ResourceLoaderText { - bool translation_remapped; + bool translation_remapped = false; String local_path; String res_path; String error_text; - FileAccess *f; + FileAccess *f = nullptr; VariantParser::StreamFile stream; @@ -53,28 +53,28 @@ class ResourceLoaderText { String type; }; - bool is_scene; + bool is_scene = false; String res_type; - bool ignore_resource_parsing; + bool ignore_resource_parsing = false; //Map<String,String> remaps; Map<int, ExtResource> ext_resources; Map<int, RES> int_resources; - int resources_total; - int resource_current; + int resources_total = 0; + int resource_current = 0; String resource_type; VariantParser::Tag next_tag; - bool use_nocache; + ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; - bool use_sub_threads; - float *progress; + bool use_sub_threads = false; + float *progress = nullptr; - mutable int lines; + mutable int lines = 0; Map<String, String> remaps; //void _printerr(); @@ -107,7 +107,7 @@ class ResourceLoaderText { friend class ResourceFormatLoaderText; - Error error; + Error error = OK; RES resource; @@ -134,7 +134,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; @@ -152,11 +152,11 @@ class ResourceFormatSaverTextInstance { Ref<PackedScene> packed_scene; - bool takeover_paths; - bool relative_paths; - bool bundle_resources; - bool skip_editor; - FileAccess *f; + bool takeover_paths = false; + bool relative_paths = false; + bool bundle_resources = false; + bool skip_editor = false; + FileAccess *f = nullptr; struct NonPersistentKey { //for resource properties generated on the fly RES base; @@ -173,7 +173,7 @@ class ResourceFormatSaverTextInstance { struct ResourceSort { RES resource; - int index; + int index = 0; bool operator<(const ResourceSort &p_right) const { return index < p_right.index; } diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 53f3dd1a4b..77c6199794 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -152,9 +152,7 @@ void Shader::_bind_methods() { } Shader::Shader() { - mode = MODE_SPATIAL; shader = RenderingServer::get_singleton()->shader_create(); - params_cache_dirty = true; } Shader::~Shader() { @@ -163,7 +161,7 @@ Shader::~Shader() { //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/scene/resources/shader.h b/scene/resources/shader.h index a3f9330055..6563181ca2 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -51,12 +51,12 @@ public: private: RID shader; - Mode mode; + Mode mode = MODE_SPATIAL; // hack the name of performance // shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make // conversion fast and save memory. - mutable bool params_cache_dirty; + mutable bool params_cache_dirty = true; mutable Map<StringName, StringName> params_cache; //map a shader param to a material param.. Map<StringName, Ref<Texture2D>> default_textures; @@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 6f3897b0cd..f8a5855d33 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -107,7 +107,6 @@ void Shape2D::_bind_methods() { Shape2D::Shape2D(const RID &p_rid) { shape = p_rid; - custom_bias = 0; } Shape2D::~Shape2D() { diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index f5814c42f8..7b00e7e426 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -38,7 +38,7 @@ class Shape2D : public Resource { OBJ_SAVE_TYPE(Shape2D); RID shape; - real_t custom_bias; + real_t custom_bias = 0.0; protected: static void _bind_methods(); diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp index e2df965138..fee8fdbde2 100644 --- a/scene/resources/skin.cpp +++ b/scene/resources/skin.cpp @@ -58,7 +58,7 @@ void Skin::set_bind_name(int p_index, const StringName &p_name) { binds_ptr[p_index].name = p_name; emit_changed(); if (notify_change) { - _change_notify(); + notify_property_list_changed(); } } @@ -81,6 +81,10 @@ void Skin::clear_binds() { emit_changed(); } +void Skin::reset_state() { + clear_binds(); +} + bool Skin::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name == "bind_count") { @@ -153,6 +157,4 @@ void Skin::_bind_methods() { } Skin::Skin() { - bind_count = 0; - binds_ptr = nullptr; } diff --git a/scene/resources/skin.h b/scene/resources/skin.h index 64fe24bbe4..f5d64f96aa 100644 --- a/scene/resources/skin.h +++ b/scene/resources/skin.h @@ -44,14 +44,15 @@ class Skin : public Resource { Vector<Bind> binds; - Bind *binds_ptr; - int bind_count; + Bind *binds_ptr = nullptr; + int bind_count = 0; protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; static void _bind_methods(); public: diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp index 8fcd92bb89..71424ba8ac 100644 --- a/scene/resources/sky.cpp +++ b/scene/resources/sky.cpp @@ -102,8 +102,6 @@ void Sky::_bind_methods() { } Sky::Sky() { - mode = PROCESS_MODE_AUTOMATIC; - radiance_size = RADIANCE_SIZE_256; sky = RS::get_singleton()->sky_create(); } diff --git a/scene/resources/sky.h b/scene/resources/sky.h index 46f645a53d..f0226d321d 100644 --- a/scene/resources/sky.h +++ b/scene/resources/sky.h @@ -59,8 +59,8 @@ public: private: RID sky; - ProcessMode mode; - RadianceSize radiance_size; + ProcessMode mode = PROCESS_MODE_AUTOMATIC; + RadianceSize radiance_size = RADIANCE_SIZE_256; Ref<Material> sky_material; protected: diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 1cdabe4662..b2efecb1cb 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -522,53 +522,59 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "}\n\n"; code += "void fragment() {\n"; - code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n"; - code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n"; - code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n"; - - code += "\t// rayleigh coefficients\n"; - code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n"; - code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n"; - code += "\t// mie coefficients from Preetham\n"; - code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n"; - - code += "\t// optical length\n"; - code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n"; - code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n"; - code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n"; - code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n"; - - code += "\t// light extinction based on thickness of atmosphere\n"; - code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n"; - - code += "\t// in scattering\n"; - code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n"; - - code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n"; - code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n"; - - code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n"; - code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n"; - - code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n"; - code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n"; - code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n"; - - code += "\t// Hack in the ground color\n"; - code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n"; - - code += "\t// Solar disk and out-scattering\n"; - code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n"; - code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n"; - code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n"; - code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n"; - code += "\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n"; - - code += "\tvec3 color = (Lin + L0) * 0.04;\n"; - code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n"; - code += "\tCOLOR *= exposure;\n"; - code += "\t// Make optional, eliminates banding\n"; - code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n"; + code += "\tif (LIGHT0_ENABLED) {\n"; + code += "\t\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n"; + code += "\t\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n"; + code += "\t\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n"; + + code += "\t\t// rayleigh coefficients\n"; + code += "\t\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n"; + code += "\t\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n"; + code += "\t\t// mie coefficients from Preetham\n"; + code += "\t\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n"; + + code += "\t\t// optical length\n"; + code += "\t\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n"; + code += "\t\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n"; + code += "\t\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n"; + code += "\t\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n"; + + code += "\t\t// light extinction based on thickness of atmosphere\n"; + code += "\t\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n"; + + code += "\t\t// in scattering\n"; + code += "\t\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n"; + + code += "\t\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n"; + code += "\t\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n"; + + code += "\t\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n"; + code += "\t\tvec3 betaMTheta = mie_beta * mie_phase;\n\n"; + + code += "\t\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n"; + code += "\t\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n"; + code += "\t\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n"; + + code += "\t\t// Hack in the ground color\n"; + code += "\t\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n"; + + code += "\t\t// Solar disk and out-scattering\n"; + code += "\t\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n"; + code += "\t\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n"; + code += "\t\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n"; + code += "\t\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n"; + code += "\t\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n"; + + code += "\t\tvec3 color = (Lin + L0) * 0.04;\n"; + code += "\t\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n"; + code += "\t\tCOLOR *= exposure;\n"; + code += "\t\t// Make optional, eliminates banding\n"; + code += "\t\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n"; + code += "\t} else {\n"; + code += "\t\t// There is no sun, so display night_sky and nothing else\n"; + code += "\t\tCOLOR = texture(night_sky, SKY_COORDS).xyz * 0.04;\n"; + code += "\t\tCOLOR *= exposure;\n"; + code += "\t}\n"; code += "}\n"; shader = RS::get_singleton()->shader_create(); @@ -591,5 +597,4 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { PhysicalSkyMaterial::~PhysicalSkyMaterial() { RS::get_singleton()->free(shader); - RS::get_singleton()->material_set_shader(_get_material(), RID()); } diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp index 008cb3e1d6..e4b4398063 100644 --- a/scene/resources/sphere_shape_3d.cpp +++ b/scene/resources/sphere_shape_3d.cpp @@ -66,7 +66,6 @@ void SphereShape3D::set_radius(float p_radius) { radius = p_radius; _update_shape(); notify_change_to_owners(); - _change_notify("radius"); } float SphereShape3D::get_radius() const { diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index a9d8eeef1c..8e47c1c15c 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -123,7 +123,6 @@ void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) { } emit_signal("texture_changed"); emit_changed(); - _change_notify("texture"); } Ref<Texture2D> StyleBoxTexture::get_texture() const { @@ -135,13 +134,6 @@ void StyleBoxTexture::set_margin_size(Side p_side, float p_size) { margin[p_side] = p_size; emit_changed(); - static const char *margin_prop[4] = { - "content_margin_left", - "content_margin_top", - "content_margin_right", - "content_margin_bottom", - }; - _change_notify(margin_prop[p_side]); } float StyleBoxTexture::get_margin_size(Side p_side) const { @@ -228,7 +220,6 @@ void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) { region_rect = p_region_rect; emit_changed(); - _change_notify("region"); } Rect2 StyleBoxTexture::get_region_rect() const { @@ -320,20 +311,9 @@ void StyleBoxTexture::_bind_methods() { BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE_FIT); } -StyleBoxTexture::StyleBoxTexture() { - for (int i = 0; i < 4; i++) { - margin[i] = 0; - expand_margin[i] = 0; - } - draw_center = true; - modulate = Color(1, 1, 1, 1); +StyleBoxTexture::StyleBoxTexture() {} - axis_h = AXIS_STRETCH_MODE_STRETCH; - axis_v = AXIS_STRETCH_MODE_STRETCH; -} - -StyleBoxTexture::~StyleBoxTexture() { -} +StyleBoxTexture::~StyleBoxTexture() {} //////////////// @@ -576,8 +556,8 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color color = outer_color; corner_point = outer_points[corner_index]; } - float x = radius * (float)cos((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.x; - float y = radius * (float)sin((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.y; + real_t x = radius * (real_t)cos((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.x; + real_t y = radius * (real_t)sin((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.y; verts.push_back(Vector2(x, y)); colors.push_back(color); } @@ -888,38 +868,9 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "anti_aliasing_size", PROPERTY_HINT_RANGE, "1,5,1"), "set_aa_size", "get_aa_size"); } -StyleBoxFlat::StyleBoxFlat() { - bg_color = Color(0.6, 0.6, 0.6); - shadow_color = Color(0, 0, 0, 0.6); - border_color = Color(0.8, 0.8, 0.8); - - blend_border = false; - draw_center = true; - anti_aliased = true; - - shadow_size = 0; - shadow_offset = Point2(0, 0); - corner_detail = 8; - aa_size = 1; +StyleBoxFlat::StyleBoxFlat() {} - border_width[0] = 0; - border_width[1] = 0; - border_width[2] = 0; - border_width[3] = 0; - - expand_margin[0] = 0; - expand_margin[1] = 0; - expand_margin[2] = 0; - expand_margin[3] = 0; - - corner_radius[0] = 0; - corner_radius[1] = 0; - corner_radius[2] = 0; - corner_radius[3] = 0; -} - -StyleBoxFlat::~StyleBoxFlat() { -} +StyleBoxFlat::~StyleBoxFlat() {} void StyleBoxLine::set_color(const Color &p_color) { color = p_color; @@ -1011,12 +962,6 @@ void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const { vs->canvas_item_add_rect(p_canvas_item, r, color); } -StyleBoxLine::StyleBoxLine() { - grow_begin = 1.0; - grow_end = 1.0; - thickness = 1; - color = Color(0.0, 0.0, 0.0); - vertical = false; -} +StyleBoxLine::StyleBoxLine() {} StyleBoxLine::~StyleBoxLine() {} diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index c133f0c825..8a273afbfd 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -86,14 +86,14 @@ public: }; private: - float expand_margin[4]; - float margin[4]; + float expand_margin[4] = {}; + float margin[4] = {}; Rect2 region_rect; Ref<Texture2D> texture; - bool draw_center; - Color modulate; - AxisStretchMode axis_h; - AxisStretchMode axis_v; + bool draw_center = true; + Color modulate = Color(1, 1, 1, 1); + AxisStretchMode axis_h = AXIS_STRETCH_MODE_STRETCH; + AxisStretchMode axis_v = AXIS_STRETCH_MODE_STRETCH; protected: virtual float get_style_margin(Side p_side) const override; @@ -139,22 +139,22 @@ VARIANT_ENUM_CAST(StyleBoxTexture::AxisStretchMode) class StyleBoxFlat : public StyleBox { GDCLASS(StyleBoxFlat, StyleBox); - Color bg_color; - Color shadow_color; - Color border_color; + Color bg_color = Color(0.6, 0.6, 0.6); + Color shadow_color = Color(0, 0, 0, 0.6); + Color border_color = Color(0.8, 0.8, 0.8); - int border_width[4]; - int expand_margin[4]; - int corner_radius[4]; + int border_width[4] = {}; + int expand_margin[4] = {}; + int corner_radius[4] = {}; - bool draw_center; - bool blend_border; - bool anti_aliased; + bool draw_center = true; + bool blend_border = false; + bool anti_aliased = true; - int corner_detail; - int shadow_size; + int corner_detail = 8; + int shadow_size = 0; Point2 shadow_offset; - int aa_size; + int aa_size = 1; protected: virtual float get_style_margin(Side p_side) const override; @@ -231,10 +231,10 @@ public: class StyleBoxLine : public StyleBox { GDCLASS(StyleBoxLine, StyleBox); Color color; - int thickness; - bool vertical; - float grow_begin; - float grow_end; + int thickness = 1; + bool vertical = false; + float grow_begin = 1.0; + float grow_end = 1.0; protected: virtual float get_style_margin(Side p_side) const override; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index dbf5268762..5ce3532d42 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -160,7 +160,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { //cap weights.resize(expected_vertices); //renormalize - float total = 0; + float total = 0.0; for (int i = 0; i < expected_vertices; i++) { total += weights[i].weight; } @@ -1196,12 +1196,7 @@ void SurfaceTool::_bind_methods() { } SurfaceTool::SurfaceTool() { - first = false; - begun = false; for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { last_custom_format[i] = CUSTOM_MAX; } - primitive = Mesh::PRIMITIVE_LINES; - skin_weights = SKIN_4_WEIGHTS; - format = 0; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index ea6069e7c1..17efdcba71 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -89,17 +89,17 @@ private: }; struct WeightSort { - int index; - float weight; + int index = 0; + float weight = 0.0; bool operator<(const WeightSort &p_right) const { return weight < p_right.weight; } }; - bool begun; - bool first; - Mesh::PrimitiveType primitive; - uint32_t format; + bool begun = false; + bool first = false; + Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_LINES; + uint32_t format = 0; Ref<Material> material; //arrays LocalVector<Vertex> vertex_array; @@ -115,7 +115,7 @@ private: Plane last_tangent; uint32_t last_smooth_group = 0; - SkinWeightCount skin_weights; + SkinWeightCount skin_weights = SKIN_4_WEIGHTS; Color last_custom[RS::ARRAY_CUSTOM_COUNT]; diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index f3f881a774..9dd00849f4 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -110,16 +110,13 @@ TextEdit *SyntaxHighlighter::get_text_edit() { } void SyntaxHighlighter::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::get_line_syntax_highlighting); + ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "line"), &SyntaxHighlighter::get_line_syntax_highlighting); ClassDB::bind_method(D_METHOD("update_cache"), &SyntaxHighlighter::update_cache); ClassDB::bind_method(D_METHOD("clear_highlighting_cache"), &SyntaxHighlighter::clear_highlighting_cache); ClassDB::bind_method(D_METHOD("get_text_edit"), &SyntaxHighlighter::get_text_edit); - ClassDB::bind_method(D_METHOD("_get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::_get_line_syntax_highlighting); - ClassDB::bind_method(D_METHOD("_update_cache"), &SyntaxHighlighter::_update_cache); - ClassDB::bind_method(D_METHOD("_clear_highlighting_cache"), &SyntaxHighlighter::_clear_highlighting_cache); - - BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "p_line"))); + BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "line"))); + BIND_VMETHOD(MethodInfo("_clear_highlighting_cache")); BIND_VMETHOD(MethodInfo("_update_cache")); } @@ -576,11 +573,11 @@ void CodeHighlighter::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_member_keyword_colors"), &CodeHighlighter::clear_member_keyword_colors); ClassDB::bind_method(D_METHOD("get_member_keyword_colors"), &CodeHighlighter::get_member_keyword_colors); - ClassDB::bind_method(D_METHOD("add_color_region", "p_start_key", "p_end_key", "p_color", "p_line_only"), &CodeHighlighter::add_color_region, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("remove_color_region", "p_start_key"), &CodeHighlighter::remove_color_region); - ClassDB::bind_method(D_METHOD("has_color_region", "p_start_key"), &CodeHighlighter::has_color_region); + ClassDB::bind_method(D_METHOD("add_color_region", "start_key", "end_key", "color", "line_only"), &CodeHighlighter::add_color_region, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("remove_color_region", "start_key"), &CodeHighlighter::remove_color_region); + ClassDB::bind_method(D_METHOD("has_color_region", "start_key"), &CodeHighlighter::has_color_region); - ClassDB::bind_method(D_METHOD("set_color_regions", "p_color_regions"), &CodeHighlighter::set_color_regions); + ClassDB::bind_method(D_METHOD("set_color_regions", "color_regions"), &CodeHighlighter::set_color_regions); ClassDB::bind_method(D_METHOD("clear_color_regions"), &CodeHighlighter::clear_color_regions); ClassDB::bind_method(D_METHOD("get_color_regions"), &CodeHighlighter::get_color_regions); diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index c9db8e31a2..f3964b0c8f 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -75,7 +75,7 @@ private: Color color; String start_key; String end_key; - bool line_only; + bool line_only = false; }; Vector<ColorRegion> color_regions; Map<int, int> color_region_cache; diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h index 3e0a74a84b..74d4f2c32c 100644 --- a/scene/resources/text_line.h +++ b/scene/resources/text_line.h @@ -45,7 +45,7 @@ class TextLine : public Reference { bool dirty = true; - float width = -1; + float width = -1.0; uint8_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; HAlign align = HALIGN_LEFT; diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index e58c157b01..a16fa8c3c4 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -50,7 +50,7 @@ class TextParagraph : public Reference { bool dirty_lines = true; - float width = -1; + float width = -1.0; uint8_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; HAlign align = HALIGN_LEFT; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 9a987ae8b1..8cccf81659 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -94,7 +94,7 @@ void ImageTexture::reload_from_file() { create_from_image(img); } else { Resource::reload_from_file(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -146,7 +146,7 @@ void ImageTexture::_reload_hook(const RID &p_hook) { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(img); RenderingServer::get_singleton()->texture_replace(texture, new_texture); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -163,7 +163,7 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image) { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image); RenderingServer::get_singleton()->texture_replace(texture, new_texture); } - _change_notify(); + notify_property_list_changed(); emit_changed(); image_stored = true; @@ -189,7 +189,7 @@ void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) { RenderingServer::get_singleton()->texture_2d_update(texture, p_image); } - _change_notify(); + notify_property_list_changed(); emit_changed(); alpha_cache.unref(); @@ -310,12 +310,7 @@ void ImageTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook); } -ImageTexture::ImageTexture() { - w = h = 0; - image_stored = false; - mipmaps = false; - format = Image::FORMAT_L8; -} +ImageTexture::ImageTexture() {} ImageTexture::~ImageTexture() { if (texture.is_valid()) { @@ -617,7 +612,7 @@ Error StreamTexture2D::load(const String &p_path) { } #endif - _change_notify(); + notify_property_list_changed(); emit_changed(); return OK; } @@ -733,11 +728,7 @@ void StreamTexture2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); } -StreamTexture2D::StreamTexture2D() { - format = Image::FORMAT_MAX; - w = 0; - h = 0; -} +StreamTexture2D::StreamTexture2D() {} StreamTexture2D::~StreamTexture2D() { if (texture.is_valid()) { @@ -745,7 +736,7 @@ StreamTexture2D::~StreamTexture2D() { } } -RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<StreamTexture2D> st; st.instance(); Error err = st->load(p_path); @@ -968,7 +959,7 @@ Error StreamTexture3D::load(const String &p_path) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } - _change_notify(); + notify_property_list_changed(); emit_changed(); return OK; } @@ -1033,13 +1024,7 @@ void StreamTexture3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); } -StreamTexture3D::StreamTexture3D() { - format = Image::FORMAT_MAX; - w = 0; - h = 0; - d = 0; - mipmaps = false; -} +StreamTexture3D::StreamTexture3D() {} StreamTexture3D::~StreamTexture3D() { if (texture.is_valid()) { @@ -1049,7 +1034,7 @@ StreamTexture3D::~StreamTexture3D() { ///////////////////////////// -RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<StreamTexture3D> st; st.instance(); Error err = st->load(p_path); @@ -1125,7 +1110,6 @@ void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) { } atlas = p_atlas; emit_changed(); - _change_notify("atlas"); } Ref<Texture2D> AtlasTexture::get_atlas() const { @@ -1138,7 +1122,6 @@ void AtlasTexture::set_region(const Rect2 &p_region) { } region = p_region; emit_changed(); - _change_notify("region"); } Rect2 AtlasTexture::get_region() const { @@ -1151,7 +1134,6 @@ void AtlasTexture::set_margin(const Rect2 &p_margin) { } margin = p_margin; emit_changed(); - _change_notify("margin"); } Rect2 AtlasTexture::get_margin() const { @@ -1161,7 +1143,6 @@ Rect2 AtlasTexture::get_margin() const { void AtlasTexture::set_filter_clip(const bool p_enable) { filter_clip = p_enable; emit_changed(); - _change_notify("filter_clip"); } bool AtlasTexture::has_filter_clip() const { @@ -1295,9 +1276,7 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { return atlas->is_pixel_opaque(x, y); } -AtlasTexture::AtlasTexture() { - filter_clip = false; -} +AtlasTexture::AtlasTexture() {} ///////////////////////////////////////// @@ -1698,9 +1677,7 @@ RID CurveTexture::get_rid() const { return _texture; } -CurveTexture::CurveTexture() { - _width = 2048; -} +CurveTexture::CurveTexture() {} CurveTexture::~CurveTexture() { if (_texture.is_valid()) { @@ -1711,9 +1688,6 @@ CurveTexture::~CurveTexture() { ////////////////// GradientTexture::GradientTexture() { - update_pending = false; - width = 2048; - _queue_update(); } @@ -1926,7 +1900,7 @@ void AnimatedTexture::_update_proxy() { } } time -= frame_limit; - _change_notify("current_frame"); + } else { break; } @@ -2128,13 +2102,6 @@ AnimatedTexture::AnimatedTexture() { proxy = RS::get_singleton()->texture_proxy_create(proxy_ph); RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true); - time = 0; - frame_count = 1; - fps = 4; - prev_ticks = 0; - current_frame = 0; - pause = false; - oneshot = false; RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy)); } @@ -2288,11 +2255,6 @@ void ImageTextureLayered::_bind_methods() { ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) { layered_type = p_layered_type; - format = Image::FORMAT_MAX; - - width = 0; - height = 0; - layers = 0; } ImageTextureLayered::~ImageTextureLayered() { @@ -2389,7 +2351,7 @@ Error StreamTextureLayered::load(const String &p_path) { RenderingServer::get_singleton()->texture_set_path(texture, p_path); } - _change_notify(); + notify_property_list_changed(); emit_changed(); return OK; } @@ -2460,11 +2422,6 @@ void StreamTextureLayered::_bind_methods() { StreamTextureLayered::StreamTextureLayered(LayeredType p_type) { layered_type = p_type; - format = Image::FORMAT_MAX; - w = 0; - h = 0; - layers = 0; - mipmaps = false; } StreamTextureLayered::~StreamTextureLayered() { @@ -2475,7 +2432,7 @@ StreamTextureLayered::~StreamTextureLayered() { ///////////////////////////////////////////////// -RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { Ref<StreamTextureLayered> st; if (p_path.get_extension().to_lower() == "stexarray") { Ref<StreamTexture2DArray> s; @@ -2593,7 +2550,7 @@ Ref<Image> CameraTexture::get_data() const { void CameraTexture::set_camera_feed_id(int p_new_id) { camera_feed_id = p_new_id; - _change_notify(); + notify_property_list_changed(); } int CameraTexture::get_camera_feed_id() const { @@ -2602,7 +2559,7 @@ int CameraTexture::get_camera_feed_id() const { void CameraTexture::set_which_feed(CameraServer::FeedImage p_which) { which_feed = p_which; - _change_notify(); + notify_property_list_changed(); } CameraServer::FeedImage CameraTexture::get_which_feed() const { @@ -2613,7 +2570,7 @@ void CameraTexture::set_camera_active(bool p_active) { Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id); if (feed.is_valid()) { feed->set_active(p_active); - _change_notify(); + notify_property_list_changed(); } } @@ -2626,10 +2583,7 @@ bool CameraTexture::get_camera_active() const { } } -CameraTexture::CameraTexture() { - camera_feed_id = 0; - which_feed = CameraServer::FEED_RGBA_IMAGE; -} +CameraTexture::CameraTexture() {} CameraTexture::~CameraTexture() { // nothing to do here yet diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 83ef0c44ae..a0d917fd86 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -83,12 +83,13 @@ class ImageTexture : public Texture2D { RES_BASE_EXTENSION("tex"); mutable RID texture; - Image::Format format; - bool mipmaps; - int w, h; + Image::Format format = Image::FORMAT_L8; + bool mipmaps = false; + int w = 0; + int h = 0; Size2 size_override; mutable Ref<BitMap> alpha_cache; - bool image_stored; + bool image_stored = false; protected: virtual void reload_from_file() override; @@ -160,8 +161,9 @@ private: Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0); String path_to_file; mutable RID texture; - Image::Format format; - int w, h; + Image::Format format = Image::FORMAT_MAX; + int w = 0; + int h = 0; mutable Ref<BitMap> alpha_cache; virtual void reload_from_file() override; @@ -209,7 +211,7 @@ public: class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -223,7 +225,7 @@ protected: Ref<Texture2D> atlas; Rect2 region; Rect2 margin; - bool filter_clip; + bool filter_clip = false; static void _bind_methods(); @@ -370,12 +372,12 @@ class ImageTextureLayered : public TextureLayered { LayeredType layered_type; mutable RID texture; - Image::Format format; + Image::Format format = Image::FORMAT_MAX; - int width; - int height; - int layers; - bool mipmaps; + int width = 0; + int height = 0; + int layers = 0; + bool mipmaps = false; Error _create_from_images(const Array &p_images); @@ -453,10 +455,12 @@ private: Error _load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit = 0); String path_to_file; mutable RID texture; - Image::Format format; - int w, h, layers; - bool mipmaps; - LayeredType layered_type; + Image::Format format = Image::FORMAT_MAX; + int w = 0; + int h = 0; + int layers = 0; + bool mipmaps = false; + LayeredType layered_type = LayeredType::LAYERED_TYPE_2D_ARRAY; virtual void reload_from_file() override; @@ -509,7 +513,7 @@ public: class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -594,9 +598,11 @@ private: Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps); String path_to_file; mutable RID texture; - Image::Format format; - int w, h, d; - bool mipmaps; + Image::Format format = Image::FORMAT_MAX; + int w = 0; + int h = 0; + int d = 0; + bool mipmaps = false; virtual void reload_from_file() override; @@ -625,7 +631,7 @@ public: class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -638,7 +644,7 @@ class CurveTexture : public Texture2D { private: mutable RID _texture; Ref<Curve> _curve; - int _width; + int _width = 2048; void _update(); @@ -680,7 +686,7 @@ class GradientTexture : public Texture2D { public: struct Point { - float offset; + float offset = 0.0; Color color; bool operator<(const Point &p_ponit) const { return offset < p_ponit.offset; @@ -689,9 +695,9 @@ public: private: Ref<Gradient> gradient; - bool update_pending; + bool update_pending = false; RID texture; - int width; + int width = 2048; void _queue_update(); void _update(); @@ -758,23 +764,19 @@ private: struct Frame { Ref<Texture2D> texture; - float delay_sec; - - Frame() { - delay_sec = 0; - } + float delay_sec = 0.0; }; Frame frames[MAX_FRAMES]; - int frame_count; - int current_frame; - bool pause; - bool oneshot; - float fps; + int frame_count = 1.0; + int current_frame = 0; + bool pause = false; + bool oneshot = false; + float fps = 4.0; - float time; + float time = 0.0; - uint64_t prev_ticks; + uint64_t prev_ticks = 0; void _update_proxy(); @@ -822,8 +824,8 @@ class CameraTexture : public Texture2D { GDCLASS(CameraTexture, Texture2D); private: - int camera_feed_id; - CameraServer::FeedImage which_feed; + int camera_feed_id = 0; + CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE; protected: static void _bind_methods(); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 5279f59d77..0405ea98bb 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -358,7 +358,7 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -373,7 +373,7 @@ void Theme::set_default_theme_font_size(int p_font_size) { default_theme_font_size = p_font_size; - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -436,7 +436,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, co } if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -463,7 +463,7 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_node_type) icon_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -506,7 +506,7 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_node_type } if (new_value) { - _change_notify(); + notify_property_list_changed(); } emit_changed(); } @@ -533,7 +533,7 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_node_ty style_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -576,7 +576,7 @@ void Theme::set_font(const StringName &p_name, const StringName &p_node_type, co } if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -604,7 +604,7 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_node_type) } font_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -637,7 +637,7 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_node_typ font_size_map[p_node_type][p_name] = p_font_size; if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -661,7 +661,7 @@ void Theme::clear_font_size(const StringName &p_name, const StringName &p_node_t ERR_FAIL_COND(!font_size_map[p_node_type].has(p_name)); font_size_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -685,7 +685,7 @@ void Theme::set_color(const StringName &p_name, const StringName &p_node_type, c color_map[p_node_type][p_name] = p_color; if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -707,7 +707,7 @@ void Theme::clear_color(const StringName &p_name, const StringName &p_node_type) ERR_FAIL_COND(!color_map[p_node_type].has(p_name)); color_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -739,7 +739,7 @@ void Theme::set_constant(const StringName &p_name, const StringName &p_node_type constant_map[p_node_type][p_name] = p_constant; if (new_value) { - _change_notify(); + notify_property_list_changed(); emit_changed(); } } @@ -761,7 +761,7 @@ void Theme::clear_constant(const StringName &p_name, const StringName &p_node_ty ERR_FAIL_COND(!constant_map[p_node_type].has(p_name)); constant_map[p_node_type].erase(p_name); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -835,7 +835,7 @@ void Theme::clear() { color_map.clear(); constant_map.clear(); - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -887,7 +887,7 @@ void Theme::copy_theme(const Ref<Theme> &p_other) { color_map = p_other->color_map; constant_map = p_other->constant_map; - _change_notify(); + notify_property_list_changed(); emit_changed(); } @@ -930,6 +930,9 @@ void Theme::get_type_list(List<StringName> *p_list) const { } } +void Theme::reset_state() { + clear(); +} void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("set_icon", "name", "node_type", "texture"), &Theme::set_icon); ClassDB::bind_method(D_METHOD("get_icon", "name", "node_type"), &Theme::get_icon); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index c802ba2536..35481126ea 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -80,6 +80,8 @@ protected: static void _bind_methods(); + virtual void reset_state() override; + public: static Ref<Theme> get_default(); static void set_default(const Ref<Theme> &p_default); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index ae536a2928..84be69d0d6 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -369,14 +369,14 @@ void TileSet::create_tile(int p_id) { ERR_FAIL_COND(tile_map.has(p_id)); tile_map[p_id] = TileData(); tile_map[p_id].autotile_data = AutotileData(); - _change_notify(""); + notify_property_list_changed(); emit_changed(); } void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].autotile_data.bitmask_mode = p_mode; - _change_notify(""); + notify_property_list_changed(); emit_changed(); } @@ -389,7 +389,6 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].texture = p_texture; emit_changed(); - _change_notify("texture"); } Ref<Texture2D> TileSet::tile_get_texture(int p_id) const { @@ -412,7 +411,6 @@ void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].modulate = p_modulate; emit_changed(); - _change_notify("modulate"); } Color TileSet::tile_get_modulate(int p_id) const { @@ -435,7 +433,6 @@ void TileSet::tile_set_region(int p_id, const Rect2 &p_region) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].region = p_region; emit_changed(); - _change_notify("region"); } Rect2 TileSet::tile_get_region(int p_id) const { @@ -447,7 +444,6 @@ void TileSet::tile_set_tile_mode(int p_id, TileMode p_tile_mode) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].tile_mode = p_tile_mode; emit_changed(); - _change_notify("tile_mode"); } TileSet::TileMode TileSet::tile_get_tile_mode(int p_id) const { @@ -669,7 +665,6 @@ void TileSet::tile_set_name(int p_id, const String &p_name) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].name = p_name; emit_changed(); - _change_notify("name"); } String TileSet::tile_get_name(int p_id) const { @@ -1060,7 +1055,7 @@ bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) { void TileSet::remove_tile(int p_id) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map.erase(p_id); - _change_notify(""); + notify_property_list_changed(); emit_changed(); } @@ -1081,9 +1076,13 @@ int TileSet::find_tile_by_name(const String &p_name) const { return -1; } +void TileSet::reset_state() { + clear(); +} + void TileSet::clear() { tile_map.clear(); - _change_notify(""); + notify_property_list_changed(); emit_changed(); } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 210520350f..0a8721f35b 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -136,6 +136,8 @@ protected: static void _bind_methods(); + virtual void reset_state() override; + public: void create_tile(int p_id); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 72724d5ee1..219cd84aa0 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -730,7 +730,7 @@ void VisualShader::set_mode(Mode p_mode) { } _queue_update(); - _change_notify(); + notify_property_list_changed(); } void VisualShader::set_graph_offset(const Vector2 &p_offset) { @@ -1095,6 +1095,12 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { return false; } +void VisualShader::reset_state() { +#ifndef _MSC_VER +#warning everything needs to be cleared here +#endif + emit_changed(); +} void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { //mode p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Node3D,CanvasItem,Particles,Sky")); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 9396a53e8b..f3f3caf15e 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -57,10 +57,10 @@ public: }; struct Connection { - int from_node; - int from_port; - int to_node; - int to_port; + int from_node = 0; + int from_port = 0; + int to_node = 0; + int to_port = 0; }; struct DefaultTextureParam { @@ -90,7 +90,7 @@ private: Vector2 graph_offset; struct RenderModeEnums { - Shader::Mode mode; + Shader::Mode mode = Shader::Mode::MODE_MAX; const char *string; }; @@ -107,7 +107,7 @@ private: uint64_t node : 32; uint64_t port : 32; }; - uint64_t key; + uint64_t key = 0; bool operator<(const ConnectionKey &p_key) const { return key < p_key.key; } @@ -126,6 +126,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: // internal methods void set_shader_type(Type p_type); Type get_shader_type() const; @@ -265,7 +267,7 @@ class VisualShaderNodeCustom : public VisualShaderNode { struct Port { String name; - int type; + int type = 0; }; List<Port> input_ports; @@ -305,9 +307,9 @@ class VisualShaderNodeInput : public VisualShaderNode { Shader::Mode shader_mode = Shader::MODE_MAX; struct Port { - Shader::Mode mode; - VisualShader::Type shader_type; - PortType type; + Shader::Mode mode = Shader::Mode::MODE_MAX; + VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX; + PortType type = PortType::PORT_TYPE_MAX; const char *name; const char *string; }; @@ -356,13 +358,13 @@ class VisualShaderNodeOutput : public VisualShaderNode { public: friend class VisualShader; - VisualShader::Type shader_type; - Shader::Mode shader_mode; + VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX; + Shader::Mode shader_mode = Shader::Mode::MODE_MAX; struct Port { - Shader::Mode mode; - VisualShader::Type shader_type; - PortType type; + Shader::Mode mode = Shader::Mode::MODE_MAX; + VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX; + PortType type = PortType::PORT_TYPE_MAX; const char *name; const char *string; }; @@ -519,7 +521,7 @@ protected: bool editable = false; struct Port { - PortType type; + PortType type = PortType::PORT_TYPE_MAX; String name; }; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 8b60c0a979..d6200059f6 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -2086,9 +2086,6 @@ String VisualShaderNodeIntFunc::get_caption() const { } int VisualShaderNodeIntFunc::get_input_port_count() const { - if (func == FUNC_CLAMP) { - return 3; - } return 1; } @@ -2097,15 +2094,6 @@ VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(i } String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const { - if (func == FUNC_CLAMP) { - if (p_port == 0) { - return ""; - } else if (p_port == 1) { - return "min"; - } else if (p_port == 2) { - return "max"; - } - } return ""; } @@ -2122,13 +2110,8 @@ String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const { } String VisualShaderNodeIntFunc::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 (func == FUNC_CLAMP) { - return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; - } - static const char *int_func_id[FUNC_SIGN + 1] = { "abs($)", - "", "-($)", "sign($)" }; @@ -2137,12 +2120,6 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader: } void VisualShaderNodeIntFunc::set_function(Function p_func) { - if (func != p_func) { - if (p_func == FUNC_CLAMP) { - set_input_port_default_value(1, 0); - set_input_port_default_value(2, 0); - } - } func = p_func; emit_changed(); } @@ -2161,10 +2138,9 @@ void VisualShaderNodeIntFunc::_bind_methods() { ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function); ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function); - ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Clamp,Negate,Sign"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function"); BIND_ENUM_CONSTANT(FUNC_ABS); - BIND_ENUM_CONSTANT(FUNC_CLAMP); BIND_ENUM_CONSTANT(FUNC_NEGATE); BIND_ENUM_CONSTANT(FUNC_SIGN); } @@ -2754,21 +2730,31 @@ VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() { set_input_port_default_value(0, Vector3()); } -////////////// Scalar Clamp +////////////// Clamp -String VisualShaderNodeScalarClamp::get_caption() const { - return "ScalarClamp"; +String VisualShaderNodeClamp::get_caption() const { + return "Clamp"; } -int VisualShaderNodeScalarClamp::get_input_port_count() const { +int VisualShaderNodeClamp::get_input_port_count() const { return 3; } -VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_input_port_type(int p_port) const { +VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_FLOAT: + return PORT_TYPE_SCALAR; + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const { +String VisualShaderNodeClamp::get_input_port_name(int p_port) const { if (p_port == 0) { return ""; } else if (p_port == 1) { @@ -2779,73 +2765,86 @@ String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeScalarClamp::get_output_port_count() const { +int VisualShaderNodeClamp::get_output_port_count() const { return 1; } -VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_output_port_type(int p_port) const { +VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_FLOAT: + return PORT_TYPE_SCALAR; + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarClamp::get_output_port_name(int p_port) const { +String VisualShaderNodeClamp::get_output_port_name(int p_port) const { return ""; } -String VisualShaderNodeScalarClamp::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 { +String VisualShaderNodeClamp::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 { return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -VisualShaderNodeScalarClamp::VisualShaderNodeScalarClamp() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 1.0); -} - -////////////// Vector Clamp - -String VisualShaderNodeVectorClamp::get_caption() const { - return "VectorClamp"; -} - -int VisualShaderNodeVectorClamp::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorClamp::get_input_port_name(int p_port) const { - if (p_port == 0) { - return ""; - } else if (p_port == 1) { - return "min"; - } else if (p_port == 2) { - return "max"; +void VisualShaderNodeClamp::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; } - return ""; + switch (p_op_type) { + case OP_TYPE_FLOAT: + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 0.0); + break; + case OP_TYPE_INT: + set_input_port_default_value(0, 0); + set_input_port_default_value(1, 0); + set_input_port_default_value(2, 0); + break; + case OP_TYPE_VECTOR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + break; + default: + break; + } + op_type = p_op_type; + emit_changed(); } -int VisualShaderNodeVectorClamp::get_output_port_count() const { - return 1; +VisualShaderNodeClamp::OpType VisualShaderNodeClamp::get_op_type() const { + return op_type; } -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +Vector<StringName> VisualShaderNodeClamp::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -String VisualShaderNodeVectorClamp::get_output_port_name(int p_port) const { - return ""; -} +void VisualShaderNodeClamp::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeClamp::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeClamp::get_op_type); -String VisualShaderNodeVectorClamp::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 { - return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_FLOAT); + BIND_ENUM_CONSTANT(OP_TYPE_INT); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeVectorClamp::VisualShaderNodeVectorClamp() { - set_input_port_default_value(0, Vector3(0, 0, 0)); - set_input_port_default_value(1, Vector3(0, 0, 0)); - set_input_port_default_value(2, Vector3(1, 1, 1)); +VisualShaderNodeClamp::VisualShaderNodeClamp() { + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 1.0); } ////////////// FaceForward @@ -2943,24 +2942,39 @@ VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() { set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); } -////////////// Vector-Scalar Step +////////////// Step -String VisualShaderNodeVectorScalarStep::get_caption() const { - return "VectorScalarStep"; +String VisualShaderNodeStep::get_caption() const { + return "Step"; } -int VisualShaderNodeVectorScalarStep::get_input_port_count() const { +int VisualShaderNodeStep::get_input_port_count() const { return 2; } -VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_SCALAR; +VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; + case 1: + return PORT_TYPE_VECTOR; + default: + break; + } + break; + default: + break; } - return PORT_TYPE_VECTOR; + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const { +String VisualShaderNodeStep::get_input_port_name(int p_port) const { if (p_port == 0) { return "edge"; } else if (p_port == 1) { @@ -2969,89 +2983,131 @@ String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeVectorScalarStep::get_output_port_count() const { +int VisualShaderNodeStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + return PORT_TYPE_VECTOR; + default: + break; + } + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorScalarStep::get_output_port_name(int p_port) const { +String VisualShaderNodeStep::get_output_port_name(int p_port) const { return ""; } -String VisualShaderNodeVectorScalarStep::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 { - return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; -} - -VisualShaderNodeVectorScalarStep::VisualShaderNodeVectorScalarStep() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); -} - -////////////// Scalar SmoothStep - -String VisualShaderNodeScalarSmoothStep::get_caption() const { - return "ScalarSmoothStep"; -} - -int VisualShaderNodeScalarSmoothStep::get_input_port_count() const { - return 3; +void VisualShaderNodeStep::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge + } + if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(1, 0.0); // x + } + break; + case OP_TYPE_VECTOR: + if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x + } + break; + case OP_TYPE_VECTOR_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(1, 0.0); // x + } + break; + default: + break; + } + op_type = p_op_type; + emit_changed(); } -VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get_input_port_type(int p_port) const { - return PORT_TYPE_SCALAR; +VisualShaderNodeStep::OpType VisualShaderNodeStep::get_op_type() const { + return op_type; } -String VisualShaderNodeScalarSmoothStep::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "edge0"; - } else if (p_port == 1) { - return "edge1"; - } else if (p_port == 2) { - return "x"; - } - return ""; +String VisualShaderNodeStep::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 { + return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } -int VisualShaderNodeScalarSmoothStep::get_output_port_count() const { - return 1; +Vector<StringName> VisualShaderNodeStep::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get_output_port_type(int p_port) const { - return PORT_TYPE_SCALAR; -} +void VisualShaderNodeStep::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeStep::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeStep::get_op_type); -String VisualShaderNodeScalarSmoothStep::get_output_port_name(int p_port) const { - return ""; -} + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); -String VisualShaderNodeScalarSmoothStep::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 { - return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeScalarSmoothStep::VisualShaderNodeScalarSmoothStep() { +VisualShaderNodeStep::VisualShaderNodeStep() { set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 0.0); } -////////////// Vector SmoothStep +////////////// SmoothStep -String VisualShaderNodeVectorSmoothStep::get_caption() const { - return "VectorSmoothStep"; +String VisualShaderNodeSmoothStep::get_caption() const { + return "SmoothStep"; } -int VisualShaderNodeVectorSmoothStep::get_input_port_count() const { +int VisualShaderNodeSmoothStep::get_input_port_count() const { return 3; } -VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; // edge0 + case 1: + return PORT_TYPE_SCALAR; // edge1 + case 2: + return PORT_TYPE_VECTOR; // x + default: + break; + } + break; + default: + break; + } + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const { +String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const { if (p_port == 0) { return "edge0"; } else if (p_port == 1) { @@ -3062,78 +3118,98 @@ String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeVectorSmoothStep::get_output_port_count() const { +int VisualShaderNodeSmoothStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + return PORT_TYPE_VECTOR; + default: + break; + } + return PORT_TYPE_SCALAR; } -String VisualShaderNodeVectorSmoothStep::get_output_port_name(int p_port) const { +String VisualShaderNodeSmoothStep::get_output_port_name(int p_port) const { return ""; } -String VisualShaderNodeVectorSmoothStep::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 { - return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; -} - -VisualShaderNodeVectorSmoothStep::VisualShaderNodeVectorSmoothStep() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); -} - -////////////// Vector-Scalar SmoothStep - -String VisualShaderNodeVectorScalarSmoothStep::get_caption() const { - return "VectorScalarSmoothStep"; -} - -int VisualShaderNodeVectorScalarSmoothStep::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_SCALAR; - } else if (p_port == 1) { - return PORT_TYPE_SCALAR; +void VisualShaderNodeSmoothStep::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge0 + set_input_port_default_value(1, 0.0); // edge1 + } + if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(2, 0.0); // x + } + break; + case OP_TYPE_VECTOR: + if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge0 + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // edge1 + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x + } + break; + case OP_TYPE_VECTOR_SCALAR: + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(0, 0.0); // edge0 + set_input_port_default_value(1, 0.0); // edge1 + } + if (op_type == OP_TYPE_SCALAR) { + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x + } + break; + default: + break; } - return PORT_TYPE_VECTOR; + op_type = p_op_type; + emit_changed(); } -String VisualShaderNodeVectorScalarSmoothStep::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "edge0"; - } else if (p_port == 1) { - return "edge1"; - } else if (p_port == 2) { - return "x"; - } - return ""; +VisualShaderNodeSmoothStep::OpType VisualShaderNodeSmoothStep::get_op_type() const { + return op_type; } -int VisualShaderNodeVectorScalarSmoothStep::get_output_port_count() const { - return 1; +String VisualShaderNodeSmoothStep::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 { + return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; +Vector<StringName> VisualShaderNodeSmoothStep::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -String VisualShaderNodeVectorScalarSmoothStep::get_output_port_name(int p_port) const { - return ""; -} +void VisualShaderNodeSmoothStep::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSmoothStep::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSmoothStep::get_op_type); -String VisualShaderNodeVectorScalarSmoothStep::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 { - return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeVectorScalarSmoothStep::VisualShaderNodeVectorScalarSmoothStep() { +VisualShaderNodeSmoothStep::VisualShaderNodeSmoothStep() { set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(2, 0.0); } ////////////// Distance @@ -3231,21 +3307,37 @@ VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() { set_input_port_default_value(2, 0.0); } -////////////// Scalar Mix +////////////// Mix -String VisualShaderNodeScalarInterp::get_caption() const { - return "ScalarMix"; +String VisualShaderNodeMix::get_caption() const { + return "Mix"; } -int VisualShaderNodeScalarInterp::get_input_port_count() const { +int VisualShaderNodeMix::get_input_port_count() const { return 3; } -VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_input_port_type(int p_port) const { +VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + if (p_port == 2) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + if (p_port == 2) { + return PORT_TYPE_SCALAR; + } + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const { +String VisualShaderNodeMix::get_input_port_name(int p_port) const { if (p_port == 0) { return "a"; } else if (p_port == 1) { @@ -3255,121 +3347,92 @@ String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const { } } -int VisualShaderNodeScalarInterp::get_output_port_count() const { +int VisualShaderNodeMix::get_output_port_count() const { return 1; } -VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_output_port_type(int p_port) const { +VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const { + switch (op_type) { + case OP_TYPE_SCALAR: + return PORT_TYPE_SCALAR; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_VECTOR_SCALAR: + return PORT_TYPE_VECTOR; + default: + break; + } return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const { +String VisualShaderNodeMix::get_output_port_name(int p_port) const { return "mix"; } -String VisualShaderNodeScalarInterp::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 { - return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; -} - -VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() { - set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 1.0); - set_input_port_default_value(2, 0.5); -} - -////////////// Vector Mix - -String VisualShaderNodeVectorInterp::get_caption() const { - return "VectorMix"; -} - -int VisualShaderNodeVectorInterp::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_input_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorInterp::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "a"; - } else if (p_port == 1) { - return "b"; - } else { - return "weight"; +void VisualShaderNodeMix::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: + set_input_port_default_value(0, 0.0); // a + set_input_port_default_value(1, 1.0); // b + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(2, 0.5); // weight + } + break; + case OP_TYPE_VECTOR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b + if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) { + set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); // weight + } + break; + case OP_TYPE_VECTOR_SCALAR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b + if (op_type == OP_TYPE_VECTOR) { + set_input_port_default_value(2, 0.5); // weight + } + break; + default: + break; } + op_type = p_op_type; + emit_changed(); } -int VisualShaderNodeVectorInterp::get_output_port_count() const { - return 1; -} - -VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const { - return "mix"; +VisualShaderNodeMix::OpType VisualShaderNodeMix::get_op_type() const { + return op_type; } -String VisualShaderNodeVectorInterp::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 { +String VisualShaderNodeMix::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 { return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); -} - -////////////// Vector Mix (by scalar) - -String VisualShaderNodeVectorScalarMix::get_caption() const { - return "VectorScalarMix"; -} - -int VisualShaderNodeVectorScalarMix::get_input_port_count() const { - return 3; -} - -VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const { - if (p_port == 2) { - return PORT_TYPE_SCALAR; - } - return PORT_TYPE_VECTOR; -} - -String VisualShaderNodeVectorScalarMix::get_input_port_name(int p_port) const { - if (p_port == 0) { - return "a"; - } else if (p_port == 1) { - return "b"; - } else { - return "weight"; - } -} - -int VisualShaderNodeVectorScalarMix::get_output_port_count() const { - return 1; +Vector<StringName> VisualShaderNodeMix::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; } -VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; -} +void VisualShaderNodeMix::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMix::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMix::get_op_type); -String VisualShaderNodeVectorScalarMix::get_output_port_name(int p_port) const { - return "mix"; -} + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type"); -String VisualShaderNodeVectorScalarMix::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 { - return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } -VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() { - set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, 0.5); +VisualShaderNodeMix::VisualShaderNodeMix() { + set_input_port_default_value(0, 0.0); // a + set_input_port_default_value(1, 1.0); // b + set_input_port_default_value(2, 0.5); // weight } ////////////// Vector Compose @@ -4847,7 +4910,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() { ////////////// Switch String VisualShaderNodeSwitch::get_caption() const { - return "VectorSwitch"; + return "Switch"; } int VisualShaderNodeSwitch::get_input_port_count() const { @@ -4858,7 +4921,23 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int if (p_port == 0) { return PORT_TYPE_BOOLEAN; } - return PORT_TYPE_VECTOR; + if (p_port == 1 || p_port == 2) { + switch (op_type) { + case OP_TYPE_FLOAT: + return PORT_TYPE_SCALAR; + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case OP_TYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + default: + break; + } + } + return PORT_TYPE_SCALAR; } String VisualShaderNodeSwitch::get_input_port_name(int p_port) const { @@ -4879,13 +4958,84 @@ int VisualShaderNodeSwitch::get_output_port_count() const { } VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR; + switch (op_type) { + case OP_TYPE_FLOAT: + return PORT_TYPE_SCALAR; + case OP_TYPE_INT: + return PORT_TYPE_SCALAR_INT; + case OP_TYPE_VECTOR: + return PORT_TYPE_VECTOR; + case OP_TYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case OP_TYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + default: + break; + } + return PORT_TYPE_SCALAR; } String VisualShaderNodeSwitch::get_output_port_name(int p_port) const { return "result"; } +void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_FLOAT: + set_input_port_default_value(1, 1.0); + set_input_port_default_value(2, 0.0); + break; + case OP_TYPE_INT: + set_input_port_default_value(1, 1); + set_input_port_default_value(2, 0); + break; + case OP_TYPE_VECTOR: + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); + set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + break; + case OP_TYPE_BOOLEAN: + set_input_port_default_value(1, true); + set_input_port_default_value(2, false); + break; + case OP_TYPE_TRANSFORM: + set_input_port_default_value(1, Transform()); + set_input_port_default_value(2, Transform()); + break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + +VisualShaderNodeSwitch::OpType VisualShaderNodeSwitch::get_op_type() const { + return op_type; +} + +Vector<StringName> VisualShaderNodeSwitch::get_editable_properties() const { + Vector<StringName> props; + props.push_back("op_type"); + return props; +} + +void VisualShaderNodeSwitch::_bind_methods() { // static + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSwitch::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSwitch::get_op_type); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_op_type", "get_op_type"); + + BIND_ENUM_CONSTANT(OP_TYPE_FLOAT); + BIND_ENUM_CONSTANT(OP_TYPE_INT); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_BOOLEAN); + BIND_ENUM_CONSTANT(OP_TYPE_TRANSFORM); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); +} + String VisualShaderNodeSwitch::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 { String code; code += "\tif(" + p_input_vars[0] + ")\n"; @@ -4902,29 +5052,6 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader:: VisualShaderNodeSwitch::VisualShaderNodeSwitch() { simple_decl = false; set_input_port_default_value(0, false); - set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); - set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); -} - -////////////// Switch(scalar) - -String VisualShaderNodeScalarSwitch::get_caption() const { - return "ScalarSwitch"; -} - -VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_input_port_type(int p_port) const { - if (p_port == 0) { - return PORT_TYPE_BOOLEAN; - } - return PORT_TYPE_SCALAR; -} - -VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_output_port_type(int p_port) const { - return PORT_TYPE_SCALAR; -} - -VisualShaderNodeScalarSwitch::VisualShaderNodeScalarSwitch() { - set_input_port_default_value(0, false); set_input_port_default_value(1, 1.0); set_input_port_default_value(2, 0.0); } @@ -5384,16 +5511,22 @@ String VisualShaderNodeMultiplyAdd::generate_code(Shader::Mode p_mode, VisualSha void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) { ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); - if (p_op_type != op_type) { - if (p_op_type == OP_TYPE_SCALAR) { + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_SCALAR: set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, 0.0); - } else { + break; + case OP_TYPE_VECTOR: set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); - } + break; + default: + break; } op_type = p_op_type; emit_changed(); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index e968bbae25..a5d0fe4649 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -826,7 +826,6 @@ class VisualShaderNodeIntFunc : public VisualShaderNode { public: enum Function { FUNC_ABS, - FUNC_CLAMP, FUNC_NEGATE, FUNC_SIGN, }; @@ -1088,29 +1087,20 @@ public: /// CLAMP /////////////////////////////////////// -class VisualShaderNodeScalarClamp : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarClamp, VisualShaderNode); +class VisualShaderNodeClamp : public VisualShaderNode { + GDCLASS(VisualShaderNodeClamp, VisualShaderNode); public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; - - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - - virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeScalarClamp(); -}; - -/////////////////////////////////////// + enum OpType { + OP_TYPE_FLOAT, + OP_TYPE_INT, + OP_TYPE_VECTOR, + OP_TYPE_MAX, + }; -class VisualShaderNodeVectorClamp : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorClamp, VisualShaderNode); +protected: + OpType op_type = OP_TYPE_FLOAT; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1123,11 +1113,18 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorClamp(); + VisualShaderNodeClamp(); }; +VARIANT_ENUM_CAST(VisualShaderNodeClamp::OpType) + /////////////////////////////////////// /// DERIVATIVE FUNCTIONS /////////////////////////////////////// @@ -1260,8 +1257,20 @@ public: /// STEP /////////////////////////////////////// -class VisualShaderNodeVectorScalarStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorScalarStep, VisualShaderNode); +class VisualShaderNodeStep : public VisualShaderNode { + GDCLASS(VisualShaderNodeStep, VisualShaderNode); + +public: + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_VECTOR_SCALAR, + OP_TYPE_MAX, + }; + +protected: + OpType op_type = OP_TYPE_SCALAR; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1274,38 +1283,36 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorScalarStep(); + VisualShaderNodeStep(); }; +VARIANT_ENUM_CAST(VisualShaderNodeStep::OpType) + /////////////////////////////////////// /// SMOOTHSTEP /////////////////////////////////////// -class VisualShaderNodeScalarSmoothStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarSmoothStep, VisualShaderNode); +class VisualShaderNodeSmoothStep : public VisualShaderNode { + GDCLASS(VisualShaderNodeSmoothStep, VisualShaderNode); public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; - - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - - virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeScalarSmoothStep(); -}; - -/////////////////////////////////////// + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_VECTOR_SCALAR, + OP_TYPE_MAX, + }; -class VisualShaderNodeVectorSmoothStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorSmoothStep, VisualShaderNode); +protected: + OpType op_type = OP_TYPE_SCALAR; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1318,32 +1325,18 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeVectorSmoothStep(); -}; - -/////////////////////////////////////// - -class VisualShaderNodeVectorScalarSmoothStep : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorScalarSmoothStep, VisualShaderNode); - -public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; + virtual Vector<StringName> get_editable_properties() const override; virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorScalarSmoothStep(); + VisualShaderNodeSmoothStep(); }; +VARIANT_ENUM_CAST(VisualShaderNodeSmoothStep::OpType) + /////////////////////////////////////// /// DISTANCE /////////////////////////////////////// @@ -1394,29 +1387,20 @@ public: /// MIX /////////////////////////////////////// -class VisualShaderNodeScalarInterp : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarInterp, VisualShaderNode); +class VisualShaderNodeMix : public VisualShaderNode { + GDCLASS(VisualShaderNodeMix, VisualShaderNode); public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; - - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; - - virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeScalarInterp(); -}; - -/////////////////////////////////////// + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_VECTOR_SCALAR, + OP_TYPE_MAX, + }; -class VisualShaderNodeVectorInterp : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorInterp, VisualShaderNode); +protected: + OpType op_type = OP_TYPE_SCALAR; + static void _bind_methods(); public: virtual String get_caption() const override; @@ -1429,32 +1413,18 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - - VisualShaderNodeVectorInterp(); -}; - -/////////////////////////////////////// - -class VisualShaderNodeVectorScalarMix : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorScalarMix, VisualShaderNode); - -public: - virtual String get_caption() const override; - - virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; - virtual String get_input_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; - virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; - virtual String get_output_port_name(int p_port) const override; + virtual Vector<StringName> get_editable_properties() const override; virtual String 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 = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeVectorScalarMix(); + VisualShaderNodeMix(); }; +VARIANT_ENUM_CAST(VisualShaderNodeMix::OpType) + /////////////////////////////////////// /// COMPOSE /////////////////////////////////////// @@ -2023,6 +1993,21 @@ class VisualShaderNodeSwitch : public VisualShaderNode { GDCLASS(VisualShaderNodeSwitch, VisualShaderNode); public: + enum OpType { + OP_TYPE_FLOAT, + OP_TYPE_INT, + OP_TYPE_VECTOR, + OP_TYPE_BOOLEAN, + OP_TYPE_TRANSFORM, + OP_TYPE_MAX, + }; + +protected: + OpType op_type = OP_TYPE_FLOAT; + + static void _bind_methods(); + +public: virtual String get_caption() const override; virtual int get_input_port_count() const override; @@ -2033,22 +2018,17 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + void set_op_type(OpType p_type); + OpType get_op_type() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual String 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 = false) const override; VisualShaderNodeSwitch(); }; -class VisualShaderNodeScalarSwitch : public VisualShaderNodeSwitch { - GDCLASS(VisualShaderNodeScalarSwitch, VisualShaderNodeSwitch); - -public: - virtual String get_caption() const override; - - virtual PortType get_input_port_type(int p_port) const override; - virtual PortType get_output_port_type(int p_port) const override; - - VisualShaderNodeScalarSwitch(); -}; +VARIANT_ENUM_CAST(VisualShaderNodeSwitch::OpType) /////////////////////////////////////// /// FRESNEL diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index cadbd93fed..156c7d0576 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -39,7 +39,7 @@ struct SpatialIndexer2D { struct CellRef { - int ref; + int ref = 0; _FORCE_INLINE_ int inc() { ref++; @@ -49,10 +49,6 @@ struct SpatialIndexer2D { ref--; return ref; } - - _FORCE_INLINE_ CellRef() { - ref = 0; - } }; struct CellKey { @@ -61,7 +57,7 @@ struct SpatialIndexer2D { int32_t x; int32_t y; }; - uint64_t key; + uint64_t key = 0; }; bool operator==(const CellKey &p_key) const { return key == p_key.key; } @@ -86,9 +82,9 @@ struct SpatialIndexer2D { Map<Viewport *, ViewportData> viewports; - bool changed; + bool changed = false; - uint64_t pass; + uint64_t pass = 0; void _notifier_update_cells(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect, bool p_add) { Point2i begin = p_rect.position; @@ -287,8 +283,6 @@ struct SpatialIndexer2D { } SpatialIndexer2D() { - pass = 0; - changed = false; cell_size = GLOBAL_DEF("world/2d/cell_size", 100); } }; diff --git a/scene/resources/world_margin_shape_3d.cpp b/scene/resources/world_margin_shape_3d.cpp index 79cbb3bbe0..28d50e1921 100644 --- a/scene/resources/world_margin_shape_3d.cpp +++ b/scene/resources/world_margin_shape_3d.cpp @@ -69,7 +69,6 @@ void WorldMarginShape3D::set_plane(Plane p_plane) { plane = p_plane; _update_shape(); notify_change_to_owners(); - _change_notify("plane"); } Plane WorldMarginShape3D::get_plane() const { diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp index 580e061496..bcfa4c4c37 100644 --- a/servers/audio/audio_filter_sw.cpp +++ b/servers/audio/audio_filter_sw.cpp @@ -58,7 +58,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { final_cutoff = 1; //don't allow less than this } - double omega = 2.0 * Math_PI * final_cutoff / sampling_rate; + double omega = Math_TAU * final_cutoff / sampling_rate; double sin_v = Math::sin(omega); double cos_v = Math::cos(omega); @@ -132,7 +132,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { double hicutoff = resonance; double centercutoff = (cutoff + resonance) / 2.0; double bandwidth = (Math::log(centercutoff) - Math::log(hicutoff)) / Math::log((double)2); - omega = 2.0 * Math_PI * centercutoff / sampling_rate; + omega = Math_TAU * centercutoff / sampling_rate; alpha = Math::sin(omega) * Math::sinh(Math::log((double)2) / 2 * bandwidth * omega / Math::sin(omega)); a0 = 1 + alpha; @@ -197,7 +197,7 @@ void AudioFilterSW::set_stages(int p_stages) { //adjust for multiple stages /* Fouriertransform kernel to obtain response */ float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) { - float freq = p_freq / sampling_rate * Math_PI * 2.0f; + float freq = p_freq / sampling_rate * Math_TAU; float cx = p_coeffs->b0, cy = 0.0; diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp new file mode 100644 index 0000000000..f37938eec8 --- /dev/null +++ b/servers/audio/effects/audio_effect_capture.cpp @@ -0,0 +1,140 @@ +/*************************************************************************/ +/* audio_effect_capture.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 "audio_effect_capture.h" + +bool AudioEffectCapture::can_get_buffer(int p_frames) const { + return buffer.data_left() >= p_frames; +} + +PackedVector2Array AudioEffectCapture::get_buffer(int p_frames) { + ERR_FAIL_COND_V(!buffer_initialized, PackedVector2Array()); + ERR_FAIL_INDEX_V(p_frames, buffer.size(), PackedVector2Array()); + int data_left = buffer.data_left(); + if (data_left < p_frames || p_frames == 0) { + return PackedVector2Array(); + } + + PackedVector2Array ret; + ret.resize(p_frames); + + Vector<AudioFrame> streaming_data; + streaming_data.resize(p_frames); + buffer.read(streaming_data.ptrw(), p_frames); + for (int32_t i = 0; i < p_frames; i++) { + ret.write[i] = Vector2(streaming_data[i].l, streaming_data[i].r); + } + return ret; +} + +void AudioEffectCapture::clear_buffer() { + const int32_t data_left = buffer.data_left(); + buffer.advance_read(data_left); +} + +void AudioEffectCapture::_bind_methods() { + ClassDB::bind_method(D_METHOD("can_get_buffer", "frames"), &AudioEffectCapture::can_get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "frames"), &AudioEffectCapture::get_buffer); + ClassDB::bind_method(D_METHOD("clear_buffer"), &AudioEffectCapture::clear_buffer); + ClassDB::bind_method(D_METHOD("set_buffer_length", "buffer_length_seconds"), &AudioEffectCapture::set_buffer_length); + ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectCapture::get_buffer_length); + ClassDB::bind_method(D_METHOD("get_frames_available"), &AudioEffectCapture::get_frames_available); + ClassDB::bind_method(D_METHOD("get_discarded_frames"), &AudioEffectCapture::get_discarded_frames); + ClassDB::bind_method(D_METHOD("get_buffer_length_frames"), &AudioEffectCapture::get_buffer_length_frames); + ClassDB::bind_method(D_METHOD("get_pushed_frames"), &AudioEffectCapture::get_pushed_frames); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_buffer_length", "get_buffer_length"); +} + +Ref<AudioEffectInstance> AudioEffectCapture::instance() { + if (!buffer_initialized) { + float target_buffer_size = AudioServer::get_singleton()->get_mix_rate() * buffer_length_seconds; + ERR_FAIL_COND_V(target_buffer_size <= 0 || target_buffer_size >= (1 << 27), Ref<AudioEffectInstance>()); + buffer.resize(nearest_shift((int)target_buffer_size)); + buffer_initialized = true; + } + + clear_buffer(); + + Ref<AudioEffectCaptureInstance> ins; + ins.instance(); + ins->base = Ref<AudioEffectCapture>(this); + + return ins; +} + +void AudioEffectCapture::set_buffer_length(float p_buffer_length_seconds) { + ERR_FAIL_COND(buffer_initialized); + + buffer_length_seconds = p_buffer_length_seconds; +} + +float AudioEffectCapture::get_buffer_length() { + return buffer_length_seconds; +} + +int AudioEffectCapture::get_frames_available() const { + ERR_FAIL_COND_V(!buffer_initialized, 0); + return buffer.data_left(); +} + +int64_t AudioEffectCapture::get_discarded_frames() const { + return discarded_frames; +} + +int AudioEffectCapture::get_buffer_length_frames() const { + ERR_FAIL_COND_V(!buffer_initialized, 0); + return buffer.size(); +} + +int64_t AudioEffectCapture::get_pushed_frames() const { + return pushed_frames; +} + +void AudioEffectCaptureInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { + RingBuffer<AudioFrame> &buffer = base->buffer; + + for (int i = 0; i < p_frame_count; i++) { + p_dst_frames[i] = p_src_frames[i]; + } + + if (buffer.space_left() >= p_frame_count) { + // Add incoming audio frames to the IO ring buffer + int32_t ret = buffer.write(p_src_frames, p_frame_count); + ERR_FAIL_COND_MSG(ret != p_frame_count, "Failed to add data to effect capture ring buffer despite sufficient space."); + atomic_add(&base->pushed_frames, p_frame_count); + } else { + atomic_add(&base->discarded_frames, p_frame_count); + } +} + +bool AudioEffectCaptureInstance::process_silence() const { + return true; +} diff --git a/servers/audio/effects/audio_effect_capture.h b/servers/audio/effects/audio_effect_capture.h new file mode 100644 index 0000000000..b154be85de --- /dev/null +++ b/servers/audio/effects/audio_effect_capture.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* audio_effect_capture.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 AUDIO_EFFECT_CAPTURE_H +#define AUDIO_EFFECT_CAPTURE_H + +#include "core/config/engine.h" +#include "core/math/audio_frame.h" +#include "core/object/reference.h" +#include "core/templates/vector.h" +#include "servers/audio/audio_effect.h" +#include "servers/audio_server.h" + +class AudioEffectCapture; + +class AudioEffectCaptureInstance : public AudioEffectInstance { + GDCLASS(AudioEffectCaptureInstance, AudioEffectInstance); + friend class AudioEffectCapture; + Ref<AudioEffectCapture> base; + +public: + virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) override; + virtual bool process_silence() const override; +}; + +class AudioEffectCapture : public AudioEffect { + GDCLASS(AudioEffectCapture, AudioEffect) + friend class AudioEffectCaptureInstance; + + RingBuffer<AudioFrame> buffer; + uint64_t discarded_frames = 0; + uint64_t pushed_frames = 0; + float buffer_length_seconds = 0.1f; + bool buffer_initialized = false; + +protected: + static void _bind_methods(); + +public: + virtual Ref<AudioEffectInstance> instance() override; + + void set_buffer_length(float p_buffer_length_seconds); + float get_buffer_length(); + + bool can_get_buffer(int p_frames) const; + PackedVector2Array get_buffer(int p_len); + void clear_buffer(); + + int get_frames_available() const; + int64_t get_discarded_frames() const; + int get_buffer_length_frames() const; + int64_t get_pushed_frames() const; +}; + +#endif // AUDIO_EFFECT_CAPTURE_H diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp index 1542273a24..76a995eb37 100644 --- a/servers/audio/effects/audio_effect_chorus.cpp +++ b/servers/audio/effects/audio_effect_chorus.cpp @@ -84,7 +84,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A if (v.cutoff == 0) { continue; } - float auxlp = expf(-2.0 * Math_PI * v.cutoff / mix_rate); + float auxlp = expf(-Math_TAU * v.cutoff / mix_rate); float c1 = 1.0 - auxlp; float c2 = auxlp; AudioFrame h = filter_h[vc]; @@ -104,7 +104,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A float phase = (float)(local_cycles & AudioEffectChorus::CYCLES_MASK) / (float)(1 << AudioEffectChorus::CYCLES_FRAC); - float wave_delay = sinf(phase * 2.0 * Math_PI) * max_depth_frames; + float wave_delay = sinf(phase * Math_TAU) * max_depth_frames; int wave_delay_frames = lrint(floor(wave_delay)); float wave_delay_frac = wave_delay - (float)wave_delay_frames; diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp index f04ab45ec1..ba50eeb0a3 100644 --- a/servers/audio/effects/audio_effect_delay.cpp +++ b/servers/audio/effects/audio_effect_delay.cpp @@ -75,7 +75,7 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au tap2_vol.r *= CLAMP(1.0 + base->tap_2_pan, 0, 1); // feedback lowpass here - float lpf_c = expf(-2.0 * Math_PI * base->feedback_lowpass / mix_rate); // 0 .. 10khz + float lpf_c = expf(-Math_TAU * base->feedback_lowpass / mix_rate); // 0 .. 10khz float lpf_ic = 1.0 - lpf_c; const AudioFrame *src = p_src_frames; diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index 8f713ace22..b79434e7c2 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -36,8 +36,8 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi const float *src = (const float *)p_src_frames; float *dst = (float *)p_dst_frames; - //float lpf_c=expf(-2.0*Math_PI*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE)); - float lpf_c = expf(-2.0 * Math_PI * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate())); + //float lpf_c=expf(-Math_TAU*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE)); + float lpf_c = expf(-Math_TAU * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate())); float lpf_ic = 1.0 - lpf_c; float drive_f = base->drive; diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp index 5e4e183ccf..9b70f03a19 100644 --- a/servers/audio/effects/audio_effect_phaser.cpp +++ b/servers/audio/effects/audio_effect_phaser.cpp @@ -38,13 +38,13 @@ void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFra float dmin = base->range_min / (sampling_rate / 2.0); float dmax = base->range_max / (sampling_rate / 2.0); - float increment = 2.f * Math_PI * (base->rate / sampling_rate); + float increment = Math_TAU * (base->rate / sampling_rate); for (int i = 0; i < p_frame_count; i++) { phase += increment; - while (phase >= Math_PI * 2.f) { - phase -= Math_PI * 2.f; + while (phase >= Math_TAU) { + phase -= Math_TAU; } float d = dmin + (dmax - dmin) * ((sin(phase) + 1.f) / 2.f); diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp index 7f73f2e880..3f7ab74a74 100644 --- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp +++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp @@ -110,10 +110,11 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames while (p_frame_count) { int to_fill = fft_size * 2 - temporal_fft_pos; to_fill = MIN(to_fill, p_frame_count); + const double to_fill_step = Math_TAU / (double)fft_size; float *fftw = temporal_fft.ptrw(); for (int i = 0; i < to_fill; i++) { //left and right buffers - float window = -0.5 * Math::cos(2.0 * Math_PI * (double)temporal_fft_pos / (double)fft_size) + 0.5; + float window = -0.5 * Math::cos(to_fill_step * (double)temporal_fft_pos) + 0.5; fftw[temporal_fft_pos * 2] = window * p_src_frames->l; fftw[temporal_fft_pos * 2 + 1] = 0; fftw[(temporal_fft_pos + fft_size * 2) * 2] = window * p_src_frames->r; diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp index 2181411b9e..e0c3eb6d3a 100644 --- a/servers/audio/effects/eq.cpp +++ b/servers/audio/effects/eq.cpp @@ -89,8 +89,8 @@ void EQ::recalculate_band_coefficients() { double frq_l = round(frq / pow(2.0, octave_size / 2.0)); double side_gain2 = POW2(Math_SQRT12); - double th = 2.0 * Math_PI * frq / mix_rate; - double th_l = 2.0 * Math_PI * frq_l / mix_rate; + double th = Math_TAU * frq / mix_rate; + double th_l = Math_TAU * frq_l / mix_rate; double c2a = side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) + side_gain2 - POW2(sin(th_l)); diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp index eb96e21659..7df2f99f67 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb.cpp @@ -91,7 +91,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { } if (params.hpf > 0) { - float hpaux = expf(-2.0 * Math_PI * params.hpf * 6000 / params.mix_rate); + float hpaux = expf(-Math_TAU * params.hpf * 6000 / params.mix_rate); float hp_a1 = (1.0 + hpaux) / 2.0; float hp_a2 = -(1.0 + hpaux) / 2.0; float hp_b1 = hpaux; @@ -293,7 +293,7 @@ void Reverb::update_parameters() { float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough) auxdmp *= auxdmp; - c.damp = expf(-2.0 * Math_PI * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz + c.damp = expf(-Math_TAU * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz } } diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index d4f7876b4b..16c6a26595 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -401,6 +401,7 @@ void AudioServer::_mix_step() { for (int k = 0; k < bus->channels.size(); k++) { if (!bus->channels[k].active) { + bus->channels.write[k].peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB); continue; } @@ -434,7 +435,7 @@ void AudioServer::_mix_step() { } } - bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + 0.0000000001), Math::linear2db(peak.r + 0.0000000001)); + bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + AUDIO_PEAK_OFFSET), Math::linear2db(peak.r + AUDIO_PEAK_OFFSET)); if (!bus->channels[k].used) { //see if any audio is contained, because channel was not used diff --git a/servers/audio_server.h b/servers/audio_server.h index 51fbc59851..a1a373e1ca 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -199,7 +199,7 @@ private: last_mix_with_audio = 0; used = false; active = false; - peak_volume = AudioFrame(0, 0); + peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB); } }; diff --git a/servers/display_server.h b/servers/display_server.h index fc34a2a228..59f59531ec 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -83,7 +83,7 @@ protected: static DisplayServerCreate server_create_functions[MAX_SERVERS]; static int server_create_count; - friend class RenderingServerDefault; + friend class RendererViewport; virtual void _set_use_vsync(bool p_enable); public: diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index 3558848dac..f503868ba5 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -55,6 +55,14 @@ * SOFTWARE. */ +void Joint2DSW::copy_settings_from(Joint2DSW *p_joint) { + set_self(p_joint->get_self()); + set_max_force(p_joint->get_max_force()); + set_bias(p_joint->get_bias()); + set_max_bias(p_joint->get_max_bias()); + disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies()); +} + static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) { real_t value = 0; diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h index 53e436b539..6050dc2775 100644 --- a/servers/physics_2d/joints_2d_sw.h +++ b/servers/physics_2d/joints_2d_sw.h @@ -49,7 +49,12 @@ public: _FORCE_INLINE_ void set_max_bias(real_t p_bias) { max_bias = p_bias; } _FORCE_INLINE_ real_t get_max_bias() const { return max_bias; } - virtual PhysicsServer2D::JointType get_type() const = 0; + virtual bool setup(real_t p_step) { return false; } + virtual void solve(real_t p_step) {} + + void copy_settings_from(Joint2DSW *p_joint); + + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_MAX; } Joint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) : Constraint2DSW(p_body_ptr, p_body_count) { bias = 0; @@ -76,7 +81,7 @@ class PinJoint2DSW : public Joint2DSW { real_t softness; public: - virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_PIN; } + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_PIN; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); @@ -113,7 +118,7 @@ class GrooveJoint2DSW : public Joint2DSW { bool correct; public: - virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_GROOVE; } + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_GROOVE; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); @@ -146,7 +151,7 @@ class DampedSpringJoint2DSW : public Joint2DSW { real_t v_coef; public: - virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_DAMPED_SPRING; } + virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_DAMPED_SPRING; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 14fcf1520a..1040437ca7 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -985,6 +985,24 @@ PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { /* JOINT API */ +RID PhysicsServer2DSW::joint_create() { + Joint2DSW *joint = memnew(Joint2DSW); + RID joint_rid = joint_owner.make_rid(joint); + joint->set_self(joint_rid); + return joint_rid; +} + +void PhysicsServer2DSW::joint_clear(RID p_joint) { + Joint2DSW *joint = joint_owner.getornull(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + Joint2DSW *empty_joint = memnew(Joint2DSW); + empty_joint->copy_settings_from(joint); + + joint_owner.replace(p_joint, empty_joint); + memdelete(joint); + } +} + void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { Joint2DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); @@ -1048,52 +1066,63 @@ bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) return joint->is_disabled_collisions_between_bodies(); } -RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b) { +void PhysicsServer2DSW::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) { Body2DSW *A = body_owner.getornull(p_body_a); - ERR_FAIL_COND_V(!A, RID()); + ERR_FAIL_COND(!A); Body2DSW *B = nullptr; if (body_owner.owns(p_body_b)) { B = body_owner.getornull(p_body_b); - ERR_FAIL_COND_V(!B, RID()); + ERR_FAIL_COND(!B); } + Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); + Joint2DSW *joint = memnew(PinJoint2DSW(p_pos, A, B)); - RID self = joint_owner.make_rid(joint); - joint->set_self(self); - return self; + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); } -RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { +void PhysicsServer2DSW::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { Body2DSW *A = body_owner.getornull(p_body_a); - ERR_FAIL_COND_V(!A, RID()); + ERR_FAIL_COND(!A); Body2DSW *B = body_owner.getornull(p_body_b); - ERR_FAIL_COND_V(!B, RID()); + ERR_FAIL_COND(!B); + + Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(GrooveJoint2DSW(p_a_groove1, p_a_groove2, p_b_anchor, A, B)); - RID self = joint_owner.make_rid(joint); - joint->set_self(self); - return self; + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); } -RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { +void PhysicsServer2DSW::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { Body2DSW *A = body_owner.getornull(p_body_a); - ERR_FAIL_COND_V(!A, RID()); + ERR_FAIL_COND(!A); Body2DSW *B = body_owner.getornull(p_body_b); - ERR_FAIL_COND_V(!B, RID()); + ERR_FAIL_COND(!B); + + Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(DampedSpringJoint2DSW(p_anchor_a, p_anchor_b, A, B)); - RID self = joint_owner.make_rid(joint); - joint->set_self(self); - return self; + + joint_owner.replace(p_joint, joint); + joint->copy_settings_from(prev_joint); + memdelete(prev_joint); } void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND(!j); - ERR_FAIL_COND(j->get_type() != JOINT_PIN); + ERR_FAIL_COND(j->get_type() != JOINT_TYPE_PIN); PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j); pin_joint->set_param(p_param, p_value); @@ -1102,7 +1131,7 @@ void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!j, 0); - ERR_FAIL_COND_V(j->get_type() != JOINT_PIN, 0); + ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_PIN, 0); PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j); return pin_joint->get_param(p_param); @@ -1111,7 +1140,7 @@ real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND(!j); - ERR_FAIL_COND(j->get_type() != JOINT_DAMPED_SPRING); + ERR_FAIL_COND(j->get_type() != JOINT_TYPE_DAMPED_SPRING); DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j); dsj->set_param(p_param, p_value); @@ -1120,7 +1149,7 @@ void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringP real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!j, 0); - ERR_FAIL_COND_V(j->get_type() != JOINT_DAMPED_SPRING, 0); + ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_DAMPED_SPRING, 0); DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j); return dsj->get_param(p_param); @@ -1128,7 +1157,7 @@ real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSprin PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const { Joint2DSW *joint = joint_owner.getornull(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_PIN); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); } @@ -1325,7 +1354,7 @@ int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) { PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr; -PhysicsServer2DSW::PhysicsServer2DSW() { +PhysicsServer2DSW::PhysicsServer2DSW(bool p_using_threads) { singletonsw = this; BroadPhase2DSW::create_func = BroadPhase2DHashGrid::_create; //BroadPhase2DSW::create_func=BroadPhase2DBasic::_create; @@ -1334,10 +1363,6 @@ PhysicsServer2DSW::PhysicsServer2DSW() { island_count = 0; active_objects = 0; collision_pairs = 0; -#ifdef NO_THREADS - using_threads = false; -#else - using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2; -#endif + using_threads = p_using_threads; flushing_queries = false; }; diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 62ea30b3f6..65c5df0fce 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -61,11 +61,11 @@ class PhysicsServer2DSW : public PhysicsServer2D { PhysicsDirectBodyState2DSW *direct_state; - mutable RID_PtrOwner<Shape2DSW> shape_owner; - mutable RID_PtrOwner<Space2DSW> space_owner; - mutable RID_PtrOwner<Area2DSW> area_owner; - mutable RID_PtrOwner<Body2DSW> body_owner; - mutable RID_PtrOwner<Joint2DSW> joint_owner; + mutable RID_PtrOwner<Shape2DSW, true> shape_owner; + mutable RID_PtrOwner<Space2DSW, true> space_owner; + mutable RID_PtrOwner<Area2DSW, true> area_owner; + mutable RID_PtrOwner<Body2DSW, true> body_owner; + mutable RID_PtrOwner<Joint2DSW, true> joint_owner; static PhysicsServer2DSW *singletonsw; @@ -255,15 +255,20 @@ public: /* JOINT API */ + virtual RID joint_create() override; + + virtual void joint_clear(RID p_joint) override; + virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value) override; virtual real_t joint_get_param(RID p_joint, JointParam p_param) const override; virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disabled) override; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override; - virtual RID pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b = RID()) override; - virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override; - virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override; + virtual void joint_make_pin(RID p_joint, const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) override; + virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override; + virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override; + virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; virtual void damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) override; @@ -287,7 +292,7 @@ public: int get_process_info(ProcessInfo p_info) override; - PhysicsServer2DSW(); + PhysicsServer2DSW(bool p_using_threads = false); ~PhysicsServer2DSW() {} }; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp index 897724fe6f..c2557d8f7f 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp @@ -113,19 +113,6 @@ void PhysicsServer2DWrapMT::finish() { } else { physics_2d_server->finish(); } - - line_shape_free_cached_ids(); - ray_shape_free_cached_ids(); - segment_shape_free_cached_ids(); - circle_shape_free_cached_ids(); - rectangle_shape_free_cached_ids(); - capsule_shape_free_cached_ids(); - convex_polygon_shape_free_cached_ids(); - concave_polygon_shape_free_cached_ids(); - - space_free_cached_ids(); - area_free_cached_ids(); - body_free_cached_ids(); } PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) : diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index fbc5b1eaa1..a6f0b1d4f1 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -73,6 +73,8 @@ public: #define ServerName PhysicsServer2D #define ServerNameWrapMT PhysicsServer2DWrapMT #define server_name physics_2d_server +#define WRITE_ACTION + #include "servers/server_wrap_mt_common.h" //FUNC1RID(shape,ShapeType); todo fix @@ -93,7 +95,7 @@ public: FUNC1RC(real_t, shape_get_custom_solver_bias, RID); //these work well, but should be used from the main thread only - bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { + bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count); } @@ -108,18 +110,18 @@ public: FUNC2RC(real_t, space_get_param, RID, SpaceParameter); // this function only works on physics process, errors and returns null otherwise - PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) { + PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->space_get_direct_state(p_space); } FUNC2(space_set_debug_contacts, RID, int); - virtual Vector<Vector2> space_get_contacts(RID p_space) const { + virtual Vector<Vector2> space_get_contacts(RID p_space) const override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>()); return physics_2d_server->space_get_contacts(p_space); } - virtual int space_get_contact_count(RID p_space) const { + virtual int space_get_contact_count(RID p_space) const override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0); return physics_2d_server->space_get_contact_count(p_space); } @@ -244,30 +246,34 @@ public: FUNC4(body_set_force_integration_callback, RID, Object *, const StringName &, const Variant &); - bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) { + bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override { return physics_2d_server->body_collide_shape(p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, r_result_count); } FUNC2(body_set_pickable, RID, bool); - bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) { + bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } - int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) { + int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } // this function only works on physics process, errors and returns null otherwise - PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) { + PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override { ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->body_get_direct_state(p_body); } /* JOINT API */ + FUNCRID(joint) + + FUNC1(joint_clear, RID) + FUNC3(joint_set_param, RID, JointParam, real_t); FUNC2RC(real_t, joint_get_param, RID, JointParam); @@ -280,9 +286,9 @@ public: //TODO need to convert this to FUNCRID, but it's a hassle.. - FUNC3R(RID, pin_joint_create, const Vector2 &, RID, RID); - FUNC5R(RID, groove_joint_create, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID); - FUNC4R(RID, damped_spring_joint_create, const Vector2 &, const Vector2 &, RID, RID); + FUNC4(joint_make_pin, RID, const Vector2 &, RID, RID); + FUNC6(joint_make_groove, RID, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID); + FUNC5(joint_make_damped_spring, RID, const Vector2 &, const Vector2 &, RID, RID); FUNC3(pin_joint_set_param, RID, PinJointParam, real_t); FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam); @@ -297,43 +303,28 @@ public: FUNC1(free, RID); FUNC1(set_active, bool); - virtual void init(); - virtual void step(real_t p_step); - virtual void sync(); - virtual void end_sync(); - virtual void flush_queries(); - virtual void finish(); + virtual void init() override; + virtual void step(real_t p_step) override; + virtual void sync() override; + virtual void end_sync() override; + virtual void flush_queries() override; + virtual void finish() override; - virtual bool is_flushing_queries() const { + virtual bool is_flushing_queries() const override { return physics_2d_server->is_flushing_queries(); } - int get_process_info(ProcessInfo p_info) { + int get_process_info(ProcessInfo p_info) override { return physics_2d_server->get_process_info(p_info); } PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread); ~PhysicsServer2DWrapMT(); - template <class T> - static PhysicsServer2D *init_server() { -#ifdef NO_THREADS - return memnew(T); // Always single unsafe when no threads are available. -#else - int tm = GLOBAL_DEF("physics/2d/thread_model", 1); - if (tm == 0) { // single unsafe - return memnew(T); - } else if (tm == 1) { // single safe - return memnew(PhysicsServer2DWrapMT(memnew(T), false)); - } else { // multi threaded - return memnew(PhysicsServer2DWrapMT(memnew(T), true)); - } -#endif - } - #undef ServerNameWrapMT #undef ServerName #undef server_name +#undef WRITE_ACTION }; #ifdef DEBUG_SYNC diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 41537f7170..05136e2501 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -1328,7 +1328,7 @@ Space2DSW::Space2DSW() { constraint_bias = 0.2; body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0); - body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI)); + body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", Math::deg2rad(8.0)); body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/2d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp index b06ade5ed3..293a7e6606 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/collision_object_3d_sw.cpp @@ -43,7 +43,7 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_trans p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); @@ -56,7 +56,7 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) { p_shape->add_owner(this); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); @@ -68,7 +68,7 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_tr shapes.write[p_index].xform = p_transform; shapes.write[p_index].xform_inv = p_transform.affine_inverse(); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); @@ -77,7 +77,7 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_tr void CollisionObject3DSW::set_shape_as_disabled(int p_idx, bool p_enable) { shapes.write[p_idx].disabled = p_enable; if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } } @@ -106,7 +106,7 @@ void CollisionObject3DSW::remove_shape(int p_index) { shapes.remove(p_index); if (!pending_shape_update_list.in_list()) { - PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list); } //_update_shapes(); //_shapes_changed(); diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index b8e056f1f4..f507cacdc3 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -31,7 +31,38 @@ #include "collision_solver_3d_sat.h" #include "core/math/geometry_3d.h" -#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02 +#include "gjk_epa.h" + +#define fallback_collision_solver gjk_epa_calculate_penetration + +// Cylinder SAT analytic methods and face-circle contact points for cylinder-trimesh and cylinder-box collision are based on ODE colliders. + +/* + * Cylinder-trimesh and Cylinder-box colliders by Alen Ladavac + * Ported to ODE by Nguyen Binh + */ + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ struct _CollectorCallback { CollisionSolver3DSW::CallbackResult callback; @@ -82,6 +113,17 @@ static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point p_callback->call(*p_points_A, closest_B); } +static void _generate_contacts_point_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A != 1); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + Vector3 closest_B = Plane(p_points_B[0], p_points_B[1], p_points_B[2]).project(*p_points_A); + + p_callback->call(*p_points_A, closest_B); +} + static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 2); @@ -128,6 +170,104 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_ p_callback->call(closest_A, closest_B); } +static void _generate_contacts_edge_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A != 2); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + const Vector3 &circle_B_pos = p_points_B[0]; + Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos; + Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos; + + real_t circle_B_radius = circle_B_line_1.length(); + Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized(); + + Plane circle_plane(circle_B_pos, circle_B_normal); + + static const int max_clip = 2; + Vector3 contact_points[max_clip]; + int num_points = 0; + + // Project edge point in circle plane. + const Vector3 &edge_A_1 = p_points_A[0]; + Vector3 proj_point_1 = circle_plane.project(edge_A_1); + + Vector3 dist_vec = proj_point_1 - circle_B_pos; + real_t dist_sq = dist_vec.length_squared(); + + // Point 1 is inside disk, add as contact point. + if (dist_sq <= circle_B_radius * circle_B_radius) { + contact_points[num_points] = edge_A_1; + ++num_points; + } + + const Vector3 &edge_A_2 = p_points_A[1]; + Vector3 proj_point_2 = circle_plane.project(edge_A_2); + + Vector3 dist_vec_2 = proj_point_2 - circle_B_pos; + real_t dist_sq_2 = dist_vec_2.length_squared(); + + // Point 2 is inside disk, add as contact point. + if (dist_sq_2 <= circle_B_radius * circle_B_radius) { + contact_points[num_points] = edge_A_2; + ++num_points; + } + + if (num_points < 2) { + Vector3 line_vec = proj_point_2 - proj_point_1; + real_t line_length_sq = line_vec.length_squared(); + + // Create a quadratic formula of the form ax^2 + bx + c = 0 + real_t a, b, c; + + a = line_length_sq; + b = 2.0 * dist_vec.dot(line_vec); + c = dist_sq - circle_B_radius * circle_B_radius; + + // Solve for t. + real_t sqrtterm = b * b - 4.0 * a * c; + + // If the term we intend to square root is less than 0 then the answer won't be real, + // so the line doesn't intersect. + if (sqrtterm >= 0) { + sqrtterm = Math::sqrt(sqrtterm); + + Vector3 edge_dir = edge_A_2 - edge_A_1; + + real_t fraction_1 = (-b - sqrtterm) / (2.0 * a); + if ((fraction_1 > 0.0) && (fraction_1 < 1.0)) { + Vector3 face_point_1 = edge_A_1 + fraction_1 * edge_dir; + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = face_point_1; + ++num_points; + } + + real_t fraction_2 = (-b + sqrtterm) / (2.0 * a); + if ((fraction_2 > 0.0) && (fraction_2 < 1.0) && !Math::is_equal_approx(fraction_1, fraction_2)) { + Vector3 face_point_2 = edge_A_1 + fraction_2 * edge_dir; + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = face_point_2; + ++num_points; + } + } + } + + // Generate contact points. + for (int i = 0; i < num_points; i++) { + const Vector3 &contact_point_A = contact_points[i]; + + real_t d = circle_plane.distance_to(contact_point_A); + Vector3 closest_B = contact_point_A - circle_plane.normal * d; + + if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) { + continue; + } + + p_callback->call(contact_point_A, closest_B); + } +} + static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 2); @@ -217,36 +357,229 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ } } -static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +static void _generate_contacts_face_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A < 3); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + const Vector3 &circle_B_pos = p_points_B[0]; + Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos; + Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos; + + // Clip face with circle segments. + static const int circle_segments = 8; + Vector3 circle_points[circle_segments]; + + real_t angle_delta = 2.0 * Math_PI / circle_segments; + + for (int i = 0; i < circle_segments; ++i) { + Vector3 point_pos = circle_B_pos; + point_pos += circle_B_line_1 * Math::cos(i * angle_delta); + point_pos += circle_B_line_2 * Math::sin(i * angle_delta); + circle_points[i] = point_pos; + } + + _generate_contacts_face_face(p_points_A, p_point_count_A, circle_points, circle_segments, p_callback); + + // Clip face with circle plane. + Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized(); + + Plane circle_plane(circle_B_pos, circle_B_normal); + + static const int max_clip = 32; + Vector3 contact_points[max_clip]; + int num_points = 0; + + for (int i = 0; i < p_point_count_A; i++) { + int i_n = (i + 1) % p_point_count_A; + + const Vector3 &edge0_A = p_points_A[i]; + const Vector3 &edge1_A = p_points_A[i_n]; + + real_t dist0 = circle_plane.distance_to(edge0_A); + real_t dist1 = circle_plane.distance_to(edge1_A); + + // First point in front of plane, generate contact point. + if (dist0 * circle_plane.d >= 0) { + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = edge0_A; + ++num_points; + } + + // Points on different sides, generate contact point. + if (dist0 * dist1 < 0) { + // calculate intersection + Vector3 rel = edge1_A - edge0_A; + real_t den = circle_plane.normal.dot(rel); + real_t dist = -(circle_plane.normal.dot(edge0_A) - circle_plane.d) / den; + Vector3 inters = edge0_A + rel * dist; + + ERR_FAIL_COND(num_points >= max_clip); + contact_points[num_points] = inters; + ++num_points; + } + } + + // Generate contact points. + for (int i = 0; i < num_points; i++) { + const Vector3 &contact_point_A = contact_points[i]; + + real_t d = circle_plane.distance_to(contact_point_A); + Vector3 closest_B = contact_point_A - circle_plane.normal * d; + + if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) { + continue; + } + + p_callback->call(contact_point_A, closest_B); + } +} + +static void _generate_contacts_circle_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_point_count_A != 3); + ERR_FAIL_COND(p_point_count_B != 3); +#endif + + const Vector3 &circle_A_pos = p_points_A[0]; + Vector3 circle_A_line_1 = p_points_A[1] - circle_A_pos; + Vector3 circle_A_line_2 = p_points_A[2] - circle_A_pos; + + real_t circle_A_radius = circle_A_line_1.length(); + Vector3 circle_A_normal = circle_A_line_1.cross(circle_A_line_2).normalized(); + + const Vector3 &circle_B_pos = p_points_B[0]; + Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos; + Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos; + + real_t circle_B_radius = circle_B_line_1.length(); + Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized(); + + static const int max_clip = 4; + Vector3 contact_points[max_clip]; + int num_points = 0; + + Vector3 centers_diff = circle_B_pos - circle_A_pos; + Vector3 norm_proj = circle_A_normal.dot(centers_diff) * circle_A_normal; + Vector3 comp_proj = centers_diff - norm_proj; + real_t proj_dist = comp_proj.length(); + if (!Math::is_zero_approx(proj_dist)) { + comp_proj /= proj_dist; + if ((proj_dist > circle_A_radius - circle_B_radius) && (proj_dist > circle_B_radius - circle_A_radius)) { + // Circles are overlapping, use the 2 points of intersection as contacts. + real_t radius_a_sqr = circle_A_radius * circle_A_radius; + real_t radius_b_sqr = circle_B_radius * circle_B_radius; + real_t d_sqr = proj_dist * proj_dist; + real_t s = (1.0 + (radius_a_sqr - radius_b_sqr) / d_sqr) * 0.5; + real_t h = Math::sqrt(MAX(radius_a_sqr - d_sqr * s * s, 0.0)); + Vector3 midpoint = circle_A_pos + s * comp_proj * proj_dist; + Vector3 h_vec = h * circle_A_normal.cross(comp_proj); + + Vector3 point_A = midpoint + h_vec; + contact_points[num_points] = point_A; + ++num_points; + + point_A = midpoint - h_vec; + contact_points[num_points] = point_A; + ++num_points; + + // Add 2 points from circle A and B along the line between the centers. + point_A = circle_A_pos + comp_proj * circle_A_radius; + contact_points[num_points] = point_A; + ++num_points; + + point_A = circle_B_pos - comp_proj * circle_B_radius - norm_proj; + contact_points[num_points] = point_A; + ++num_points; + } // Otherwise one circle is inside the other one, use 3 arbitrary equidistant points. + } // Otherwise circles are concentric, use 3 arbitrary equidistant points. + + if (num_points == 0) { + // Generate equidistant points. + if (circle_A_radius < circle_B_radius) { + // Circle A inside circle B. + for (int i = 0; i < 3; ++i) { + Vector3 circle_A_point = circle_A_pos; + circle_A_point += circle_A_line_1 * Math::cos(2.0 * Math_PI * i / 3.0); + circle_A_point += circle_A_line_2 * Math::sin(2.0 * Math_PI * i / 3.0); + + contact_points[num_points] = circle_A_point; + ++num_points; + } + } else { + // Circle B inside circle A. + for (int i = 0; i < 3; ++i) { + Vector3 circle_B_point = circle_B_pos; + circle_B_point += circle_B_line_1 * Math::cos(2.0 * Math_PI * i / 3.0); + circle_B_point += circle_B_line_2 * Math::sin(2.0 * Math_PI * i / 3.0); + + Vector3 circle_A_point = circle_B_point - norm_proj; + + contact_points[num_points] = circle_A_point; + ++num_points; + } + } + } + + Plane circle_B_plane(circle_B_pos, circle_B_normal); + + // Generate contact points. + for (int i = 0; i < num_points; i++) { + const Vector3 &contact_point_A = contact_points[i]; + + real_t d = circle_B_plane.distance_to(contact_point_A); + Vector3 closest_B = contact_point_A - circle_B_plane.normal * d; + + if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) { + continue; + } + + p_callback->call(contact_point_A, closest_B); + } +} + +static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, Shape3DSW::FeatureType p_feature_type_A, const Vector3 *p_points_B, int p_point_count_B, Shape3DSW::FeatureType p_feature_type_B, _CollectorCallback *p_callback) { #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 1); ERR_FAIL_COND(p_point_count_B < 1); #endif - static const GenerateContactsFunc generate_contacts_func_table[3][3] = { + static const GenerateContactsFunc generate_contacts_func_table[4][4] = { { _generate_contacts_point_point, _generate_contacts_point_edge, _generate_contacts_point_face, + _generate_contacts_point_circle, }, { nullptr, _generate_contacts_edge_edge, _generate_contacts_face_face, + _generate_contacts_edge_circle, }, { nullptr, nullptr, _generate_contacts_face_face, - } + _generate_contacts_face_circle, + }, + { + nullptr, + nullptr, + nullptr, + _generate_contacts_circle_circle, + }, }; int pointcount_B; int pointcount_A; const Vector3 *points_A; const Vector3 *points_B; + int version_A; + int version_B; - if (p_point_count_A > p_point_count_B) { + if (p_feature_type_A > p_feature_type_B) { //swap p_callback->swap = !p_callback->swap; p_callback->normal = -p_callback->normal; @@ -255,16 +588,17 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po pointcount_A = p_point_count_B; points_A = p_points_B; points_B = p_points_A; + version_A = p_feature_type_B; + version_B = p_feature_type_A; } else { pointcount_B = p_point_count_B; pointcount_A = p_point_count_A; points_A = p_points_A; points_B = p_points_B; + version_A = p_feature_type_A; + version_B = p_feature_type_B; } - int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1; - int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1; - GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B]; ERR_FAIL_COND(!contacts_func); contacts_func(points_A, pointcount_A, points_B, pointcount_B, p_callback); @@ -346,6 +680,17 @@ public: return true; } + static _FORCE_INLINE_ void test_contact_points(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { + SeparatorAxisTest<ShapeA, ShapeB, withMargin> *separator = (SeparatorAxisTest<ShapeA, ShapeB, withMargin> *)p_userdata; + Vector3 axis = (p_point_B - p_point_A); + real_t depth = axis.length(); + + // Filter out bogus directions with a treshold and re-testing axis. + if (separator->best_depth - depth > 0.001) { + separator->test_axis(axis / depth); + } + } + _FORCE_INLINE_ void generate_contacts() { // nothing to do, don't generate if (best_axis == Vector3(0.0, 0.0, 0.0)) { @@ -365,7 +710,8 @@ public: Vector3 supports_A[max_supports]; int support_count_A; - shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A); + Shape3DSW::FeatureType support_type_A; + shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A, support_type_A); for (int i = 0; i < support_count_A; i++) { supports_A[i] = transform_A->xform(supports_A[i]); } @@ -378,7 +724,8 @@ public: Vector3 supports_B[max_supports]; int support_count_B; - shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B); + Shape3DSW::FeatureType support_type_B; + shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B, support_type_B); for (int i = 0; i < support_count_B; i++) { supports_B[i] = transform_B->xform(supports_B[i]); } @@ -393,7 +740,7 @@ public: if (callback->prev_axis) { *callback->prev_axis = best_axis; } - _generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback); + _generate_contacts_from_supports(supports_A, support_count_A, support_type_A, supports_B, support_count_B, support_type_B, callback); callback->collided = true; } @@ -529,6 +876,61 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t template <bool withMargin> static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<SphereShape3DSW, CylinderShape3DSW, withMargin> separator(sphere_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + if (!separator.test_previous_axis()) { + return; + } + + // Cylinder B end caps. + Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1).normalized(); + if (!separator.test_axis(cylinder_B_axis)) { + return; + } + + Vector3 cylinder_diff = p_transform_b.origin - p_transform_a.origin; + + // Cylinder B lateral surface. + if (!separator.test_axis(cylinder_B_axis.cross(cylinder_diff).cross(cylinder_B_axis).normalized())) { + return; + } + + // Closest point to cylinder caps. + const Vector3 &sphere_center = p_transform_a.origin; + Vector3 cyl_axis = p_transform_b.basis.get_axis(1); + Vector3 cap_axis = p_transform_b.basis.get_axis(0); + real_t height_scale = cyl_axis.length(); + real_t cap_dist = cylinder_B->get_height() * 0.5 * height_scale; + cyl_axis /= height_scale; + real_t radius_scale = cap_axis.length(); + real_t cap_radius = cylinder_B->get_radius() * radius_scale; + + for (int i = 0; i < 2; i++) { + Vector3 cap_dir = ((i == 0) ? cyl_axis : -cyl_axis); + Vector3 cap_pos = p_transform_b.origin + cap_dir * cap_dist; + + Vector3 closest_point; + + Vector3 diff = sphere_center - cap_pos; + Vector3 proj = diff - cap_dir.dot(diff) * cap_dir; + + real_t proj_len = proj.length(); + if (Math::is_zero_approx(proj_len)) { + // Point is equidistant to all circle points. + continue; + } + + closest_point = cap_pos + (cap_radius / proj_len) * proj; + + if (!separator.test_axis((closest_point - sphere_center).normalized())) { + return; + } + } + + separator.generate_contacts(); } template <bool withMargin> @@ -739,7 +1141,7 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran // faces of A for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_a.basis.get_axis(i); + Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); if (!separator.test_axis(axis)) { return; @@ -826,6 +1228,115 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran template <bool withMargin> static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<BoxShape3DSW, CylinderShape3DSW, withMargin> separator(box_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + if (!separator.test_previous_axis()) { + return; + } + + // Faces of A. + for (int i = 0; i < 3; i++) { + Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); + + if (!separator.test_axis(axis)) { + return; + } + } + + Vector3 cyl_axis = p_transform_b.basis.get_axis(1).normalized(); + + // Cylinder end caps. + { + if (!separator.test_axis(cyl_axis)) { + return; + } + } + + // Edges of A, cylinder lateral surface. + for (int i = 0; i < 3; i++) { + Vector3 box_axis = p_transform_a.basis.get_axis(i); + Vector3 axis = box_axis.cross(cyl_axis); + if (Math::is_zero_approx(axis.length_squared())) { + continue; + } + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + + // Gather points of A. + Vector3 vertices_A[8]; + Vector3 box_extent = box_A->get_half_extents(); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 2; k++) { + Vector3 extent = box_extent; + extent.x *= (i * 2 - 1); + extent.y *= (j * 2 - 1); + extent.z *= (k * 2 - 1); + Vector3 &point = vertices_A[i * 2 * 2 + j * 2 + k]; + point = p_transform_a.origin; + for (int l = 0; l < 3; l++) { + point += p_transform_a.basis.get_axis(l) * extent[l]; + } + } + } + } + + // Points of A, cylinder lateral surface. + for (int i = 0; i < 8; i++) { + const Vector3 &point = vertices_A[i]; + Vector3 axis = Plane(cyl_axis, 0).project(point).normalized(); + + if (!separator.test_axis(axis)) { + return; + } + } + + // Edges of A, cylinder end caps rim. + int edges_start_A[12] = { 0, 2, 4, 6, 0, 1, 4, 5, 0, 1, 2, 3 }; + int edges_end_A[12] = { 1, 3, 5, 7, 2, 3, 6, 7, 4, 5, 6, 7 }; + + Vector3 cap_axis = cyl_axis * (cylinder_B->get_height() * 0.5); + + for (int i = 0; i < 2; i++) { + Vector3 cap_pos = p_transform_b.origin + ((i == 0) ? cap_axis : -cap_axis); + + for (int e = 0; e < 12; e++) { + const Vector3 &edge_start = vertices_A[edges_start_A[e]]; + const Vector3 &edge_end = vertices_A[edges_end_A[e]]; + + Vector3 edge_dir = (edge_end - edge_start); + edge_dir.normalize(); + + real_t edge_dot = edge_dir.dot(cyl_axis); + if (Math::is_zero_approx(edge_dot)) { + // Edge is perpendicular to cylinder axis. + continue; + } + + // Calculate intersection between edge and circle plane. + Vector3 edge_diff = cap_pos - edge_start; + real_t diff_dot = edge_diff.dot(cyl_axis); + Vector3 intersection = edge_start + edge_dir * diff_dot / edge_dot; + + // Calculate tangent that touches intersection. + Vector3 tangent = (cap_pos - intersection).cross(cyl_axis); + + // Axis is orthogonal both to tangent and edge direction. + Vector3 axis = tangent.cross(edge_dir); + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + } + + separator.generate_contacts(); } template <bool withMargin> @@ -1111,6 +1622,19 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_ template <bool withMargin> static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin> separator(capsule_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; + + // Fallback to generic algorithm to find the best separating axis. + if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) { + return; + } + + separator.generate_contacts(); } template <bool withMargin> @@ -1236,14 +1760,165 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra template <bool withMargin> static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); + const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b); + + SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin> separator(cylinder_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + Vector3 cylinder_A_axis = p_transform_a.basis.get_axis(1); + Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1); + + if (!separator.test_previous_axis()) { + return; + } + + // Cylinder A end caps. + if (!separator.test_axis(cylinder_A_axis.normalized())) { + return; + } + + // Cylinder B end caps. + if (!separator.test_axis(cylinder_A_axis.normalized())) { + return; + } + + Vector3 cylinder_diff = p_transform_b.origin - p_transform_a.origin; + + // Cylinder A lateral surface. + if (!separator.test_axis(cylinder_A_axis.cross(cylinder_diff).cross(cylinder_A_axis).normalized())) { + return; + } + + // Cylinder B lateral surface. + if (!separator.test_axis(cylinder_B_axis.cross(cylinder_diff).cross(cylinder_B_axis).normalized())) { + return; + } + + real_t proj = cylinder_A_axis.cross(cylinder_B_axis).cross(cylinder_B_axis).dot(cylinder_A_axis); + if (Math::is_zero_approx(proj)) { + // Parallel cylinders, handle with specific axes only. + // Note: GJKEPA with no margin can lead to degenerate cases in this situation. + separator.generate_contacts(); + return; + } + + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points; + + // Fallback to generic algorithm to find the best separating axis. + if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) { + return; + } + + separator.generate_contacts(); } template <bool withMargin> static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); + const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); + + SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(cylinder_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin>::test_contact_points; + + // Fallback to generic algorithm to find the best separating axis. + if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) { + return; + } + + separator.generate_contacts(); } template <bool withMargin> static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { + const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a); + const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); + + SeparatorAxisTest<CylinderShape3DSW, FaceShape3DSW, withMargin> separator(cylinder_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); + + if (!separator.test_previous_axis()) { + return; + } + + Vector3 vertex[3] = { + p_transform_b.xform(face_B->vertex[0]), + p_transform_b.xform(face_B->vertex[1]), + p_transform_b.xform(face_B->vertex[2]), + }; + + // Face B normal. + if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) { + return; + } + + Vector3 cyl_axis = p_transform_a.basis.get_axis(1).normalized(); + + // Cylinder end caps. + { + if (!separator.test_axis(cyl_axis)) { + return; + } + } + + // Edges of B, cylinder lateral surface. + for (int i = 0; i < 3; i++) { + Vector3 edge_axis = vertex[i] - vertex[(i + 1) % 3]; + Vector3 axis = edge_axis.cross(cyl_axis); + if (Math::is_zero_approx(axis.length_squared())) { + continue; + } + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + + // Points of B, cylinder lateral surface. + for (int i = 0; i < 3; i++) { + const Vector3 &point = vertex[i]; + Vector3 axis = Plane(cyl_axis, 0).project(point).normalized(); + + if (!separator.test_axis(axis)) { + return; + } + } + + // Edges of B, cylinder end caps rim. + Vector3 cap_axis = cyl_axis * (cylinder_A->get_height() * 0.5); + + for (int i = 0; i < 2; i++) { + Vector3 cap_pos = p_transform_a.origin + ((i == 0) ? cap_axis : -cap_axis); + + for (int j = 0; j < 3; j++) { + const Vector3 &edge_start = vertex[j]; + const Vector3 &edge_end = vertex[(j + 1) % 3]; + Vector3 edge_dir = edge_end - edge_start; + edge_dir.normalize(); + + real_t edge_dot = edge_dir.dot(cyl_axis); + if (Math::is_zero_approx(edge_dot)) { + // Edge is perpendicular to cylinder axis. + continue; + } + + // Calculate intersection between edge and circle plane. + Vector3 edge_diff = cap_pos - edge_start; + real_t diff_dot = edge_diff.dot(cyl_axis); + Vector3 intersection = edge_start + edge_dir * diff_dot / edge_dot; + + // Calculate tangent that touches intersection. + Vector3 tangent = (cap_pos - intersection).cross(cyl_axis); + + // Axis is orthogonal both to tangent and edge direction. + Vector3 axis = tangent.cross(edge_dir); + + if (!separator.test_axis(axis.normalized())) { + return; + } + } + } + + separator.generate_contacts(); } template <bool withMargin> diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp index 1150696b84..fd9ea00d92 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/collision_solver_3d_sw.cpp @@ -46,8 +46,24 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T static const int max_supports = 16; Vector3 supports[max_supports]; int support_count; - - p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count); + Shape3DSW::FeatureType support_type; + p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type); + + if (support_type == Shape3DSW::FEATURE_CIRCLE) { + ERR_FAIL_COND_V(support_count != 3, false); + + Vector3 circle_pos = supports[0]; + Vector3 circle_axis_1 = supports[1] - circle_pos; + Vector3 circle_axis_2 = supports[2] - circle_pos; + + // Use 3 equidistant points on the circle. + for (int i = 0; i < 3; ++i) { + Vector3 vertex_pos = circle_pos; + vertex_pos += circle_axis_1 * Math::cos(2.0 * Math_PI * i / 3.0); + vertex_pos += circle_axis_2 * Math::sin(2.0 * Math_PI * i / 3.0); + supports[i] = vertex_pos; + } + } bool found = false; @@ -265,8 +281,25 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const static const int max_supports = 16; Vector3 supports[max_supports]; int support_count; + Shape3DSW::FeatureType support_type; + + p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type); - p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count); + if (support_type == Shape3DSW::FEATURE_CIRCLE) { + ERR_FAIL_COND_V(support_count != 3, false); + + Vector3 circle_pos = supports[0]; + Vector3 circle_axis_1 = supports[1] - circle_pos; + Vector3 circle_axis_2 = supports[2] - circle_pos; + + // Use 3 equidistant points on the circle. + for (int i = 0; i < 3; ++i) { + Vector3 vertex_pos = circle_pos; + vertex_pos += circle_axis_1 * Math::cos(2.0 * Math_PI * i / 3.0); + vertex_pos += circle_axis_2 * Math::sin(2.0 * Math_PI * i / 3.0); + supports[i] = vertex_pos; + } + } bool collided = false; Vector3 closest; diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index dafd2feb8b..aa7c11eec5 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -64,7 +64,7 @@ GJK-EPA collision solver by Nathanael Presson, 2008 /* GJK */ #define GJK_MAX_ITERATIONS 128 -#define GJK_ACCURARY ((real_t)0.0001) +#define GJK_ACCURACY ((real_t)0.0001) #define GJK_MIN_DISTANCE ((real_t)0.0001) #define GJK_DUPLICATED_EPS ((real_t)0.0001) #define GJK_SIMPLEX2_EPS ((real_t)0.0) @@ -72,10 +72,13 @@ GJK-EPA collision solver by Nathanael Presson, 2008 #define GJK_SIMPLEX4_EPS ((real_t)0.0) /* EPA */ -#define EPA_MAX_VERTICES 64 +#define EPA_MAX_VERTICES 128 #define EPA_MAX_FACES (EPA_MAX_VERTICES*2) #define EPA_MAX_ITERATIONS 255 -#define EPA_ACCURACY ((real_t)0.0001) +// -- GODOT start -- +//#define EPA_ACCURACY ((real_t)0.0001) +#define EPA_ACCURACY ((real_t)0.00001) +// -- GODOT end -- #define EPA_FALLBACK (10*EPA_ACCURACY) #define EPA_PLANE_EPS ((real_t)0.00001) #define EPA_INSIDE_EPS ((real_t)0.01) @@ -237,7 +240,7 @@ struct GJK /* Check for termination */ const real_t omega=vec3_dot(m_ray,w)/rl; alpha=MAX(omega,alpha); - if(((rl-alpha)-(GJK_ACCURARY*rl))<=0) + if(((rl-alpha)-(GJK_ACCURACY*rl))<=0) {/* Return old simplex */ removevertice(m_simplices[m_current]); break; @@ -466,7 +469,7 @@ struct GJK if(ng&&(Math::abs(vl)>GJK_SIMPLEX4_EPS)) { real_t mindist=-1; - real_t subw[3]; + real_t subw[3] = {0.f, 0.f, 0.f}; U subm=0; for(U i=0;i<3;++i) { @@ -512,7 +515,6 @@ struct GJK { Vector3 n; real_t d; - real_t p; sSV* c[3]; sFace* f[3]; sFace* l[2]; @@ -661,8 +663,7 @@ struct GJK remove(m_hull,best); append(m_stock,best); best=findbest(); - if(best->p>=outer.p) { outer=*best; -} + outer=*best; } else { m_status=eStatus::InvalidHull;break; } } else { m_status=eStatus::AccuraryReached;break; } } else { m_status=eStatus::OutOfVertices;break; } @@ -688,24 +689,54 @@ struct GJK } } /* Fallback */ - m_status = eStatus::FallBack; - m_normal = -guess; - const real_t nl=m_normal.length(); - if(nl>0) { - m_normal = m_normal/nl; + m_status = eStatus::FallBack; + m_normal = -guess; + const real_t nl = m_normal.length(); + if (nl > 0) { + m_normal = m_normal/nl; } else { - m_normal = Vector3(1,0,0); -} + m_normal = Vector3(1,0,0); + } m_depth = 0; m_result.rank=1; m_result.c[0]=simplex.c[0]; m_result.p[0]=1; return(m_status); } + + bool getedgedist(sFace* face, sSV* a, sSV* b, real_t& dist) + { + const Vector3 ba = b->w - a->w; + const Vector3 n_ab = vec3_cross(ba, face->n); // Outward facing edge normal direction, on triangle plane + const real_t a_dot_nab = vec3_dot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required + + if (a_dot_nab < 0) { + // Outside of edge a->b + const real_t ba_l2 = ba.length_squared(); + const real_t a_dot_ba = vec3_dot(a->w, ba); + const real_t b_dot_ba = vec3_dot(b->w, ba); + + if (a_dot_ba > 0) { + // Pick distance vertex a + dist = a->w.length(); + } else if (b_dot_ba < 0) { + // Pick distance vertex b + dist = b->w.length(); + } else { + // Pick distance to edge a->b + const real_t a_dot_b = vec3_dot(a->w, b->w); + dist = Math::sqrt(MAX((a->w.length_squared() * b->w.length_squared() - a_dot_b * a_dot_b) / ba_l2, 0.0)); + } + + return true; + } + + return false; + } + sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) { - if(m_stock.root) - { + if (m_stock.root) { sFace* face=m_stock.root; remove(m_stock,face); append(m_hull,face); @@ -716,23 +747,23 @@ struct GJK face->n = vec3_cross(b->w-a->w,c->w-a->w); const real_t l=face->n.length(); const bool v=l>EPA_ACCURACY; - face->p = MIN(MIN( - vec3_dot(a->w,vec3_cross(face->n,a->w-b->w)), - vec3_dot(b->w,vec3_cross(face->n,b->w-c->w))), - vec3_dot(c->w,vec3_cross(face->n,c->w-a->w))) / - (v?l:1); - face->p = face->p>=-EPA_INSIDE_EPS?0:face->p; - if(v) - { - face->d = vec3_dot(a->w,face->n)/l; + if (v) { + if (!(getedgedist(face, a, b, face->d) || + getedgedist(face, b, c, face->d) || + getedgedist(face, c, a, face->d))) { + // Origin projects to the interior of the triangle + // Use distance to triangle plane + face->d = vec3_dot(a->w, face->n) / l; + } face->n /= l; - if(forced||(face->d>=-EPA_PLANE_EPS)) - { + if (forced||(face->d>=-EPA_PLANE_EPS)) { return(face); - } else { m_status=eStatus::NonConvex; -} - } else { m_status=eStatus::Degenerated; -} + } else { + m_status=eStatus::NonConvex; + } + } else { + m_status=eStatus::Degenerated; + } remove(m_hull,face); append(m_stock,face); return(nullptr); @@ -747,15 +778,13 @@ struct GJK { sFace* minf=m_hull.root; real_t mind=minf->d*minf->d; - real_t maxp=minf->p; for(sFace* f=minf->l[1];f;f=f->l[1]) { const real_t sqd=f->d*f->d; - if((f->p>=maxp)&&(sqd<mind)) + if(sqd<mind) { minf=f; mind=sqd; - maxp=f->p; } } return(minf); diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp index 7b10257157..9c4493f4a2 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp @@ -92,9 +92,9 @@ ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Trans m_rbAFrame = rbAFrame; m_rbBFrame = rbBFrame; - m_swingSpan1 = Math_PI / 4.0; - m_swingSpan2 = Math_PI / 4.0; - m_twistSpan = Math_PI * 2; + m_swingSpan1 = Math_TAU / 8.0; + m_swingSpan2 = Math_TAU / 8.0; + m_twistSpan = Math_TAU; m_biasFactor = 0.3f; m_relaxationFactor = 1.0f; diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h index c38edc5737..4e4d4e7f0c 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h @@ -102,7 +102,7 @@ public: bool m_solveSwingLimit; public: - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_CONE_TWIST; } virtual bool setup(real_t p_timestep); virtual void solve(real_t p_timestep); diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h index 2ae6fe85fa..d61a033231 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -234,7 +234,7 @@ protected: public: Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_6DOF; } virtual bool setup(real_t p_timestep); virtual void solve(real_t p_timestep); diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h index 028a8b8c72..b6117aa0bc 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.h +++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h @@ -96,7 +96,7 @@ class HingeJoint3DSW : public Joint3DSW { real_t m_appliedImpulse; public: - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_HINGE; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/pin_joint_3d_sw.h index e28fbec6cd..1875983527 100644 --- a/servers/physics_3d/joints/pin_joint_3d_sw.h +++ b/servers/physics_3d/joints/pin_joint_3d_sw.h @@ -74,7 +74,7 @@ class PinJoint3DSW : public Joint3DSW { Vector3 m_pivotInB; public: - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_PIN; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_PIN; } virtual bool setup(real_t p_step); virtual void solve(real_t p_step); diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h index 196e60d19d..f52f6ace27 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.h +++ b/servers/physics_3d/joints/slider_joint_3d_sw.h @@ -243,7 +243,7 @@ public: bool setup(real_t p_step); void solve(real_t p_step); - virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; } + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_SLIDER; } }; #endif // SLIDER_JOINT_SW_H diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/joints_3d_sw.h index cad05b6702..1fe573c69e 100644 --- a/servers/physics_3d/joints_3d_sw.h +++ b/servers/physics_3d/joints_3d_sw.h @@ -36,7 +36,16 @@ class Joint3DSW : public Constraint3DSW { public: - virtual PhysicsServer3D::JointType get_type() const = 0; + virtual bool setup(real_t p_step) { return false; } + virtual void solve(real_t p_step) {} + + void copy_settings_from(Joint3DSW *p_joint) { + set_self(p_joint->get_self()); + set_priority(p_joint->get_priority()); + disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies()); + } + + virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_MAX; } _FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) : Constraint3DSW(p_body_ptr, p_body_count) { } diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index b554a23bf2..735e9094d2 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -43,47 +43,63 @@ #define FLUSH_QUERY_CHECK(m_object) \ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); -RID PhysicsServer3DSW::shape_create(ShapeType p_shape) { - Shape3DSW *shape = nullptr; - switch (p_shape) { - case SHAPE_PLANE: { - shape = memnew(PlaneShape3DSW); - } break; - case SHAPE_RAY: { - shape = memnew(RayShape3DSW); - } break; - case SHAPE_SPHERE: { - shape = memnew(SphereShape3DSW); - } break; - case SHAPE_BOX: { - shape = memnew(BoxShape3DSW); - } break; - case SHAPE_CAPSULE: { - shape = memnew(CapsuleShape3DSW); - } break; - case SHAPE_CYLINDER: { - ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings."); - } break; - case SHAPE_CONVEX_POLYGON: { - shape = memnew(ConvexPolygonShape3DSW); - } break; - case SHAPE_CONCAVE_POLYGON: { - shape = memnew(ConcavePolygonShape3DSW); - } break; - case SHAPE_HEIGHTMAP: { - shape = memnew(HeightMapShape3DSW); - } break; - case SHAPE_CUSTOM: { - ERR_FAIL_V(RID()); - - } break; - } - - RID id = shape_owner.make_rid(shape); - shape->set_self(id); - - return id; -}; +RID PhysicsServer3DSW::plane_shape_create() { + Shape3DSW *shape = memnew(PlaneShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::ray_shape_create() { + Shape3DSW *shape = memnew(RayShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::sphere_shape_create() { + Shape3DSW *shape = memnew(SphereShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::box_shape_create() { + Shape3DSW *shape = memnew(BoxShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::capsule_shape_create() { + Shape3DSW *shape = memnew(CapsuleShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::cylinder_shape_create() { + Shape3DSW *shape = memnew(CylinderShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::convex_polygon_shape_create() { + Shape3DSW *shape = memnew(ConvexPolygonShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::concave_polygon_shape_create() { + Shape3DSW *shape = memnew(ConcavePolygonShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::heightmap_shape_create() { + Shape3DSW *shape = memnew(HeightMapShape3DSW); + RID rid = shape_owner.make_rid(shape); + shape->set_self(rid); + return rid; +} +RID PhysicsServer3DSW::custom_shape_create() { + ERR_FAIL_V(RID()); +} void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) { Shape3DSW *shape = shape_owner.getornull(p_shape); @@ -174,7 +190,7 @@ real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) c PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) { Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, nullptr); - ERR_FAIL_COND_V_MSG(space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); return space->get_direct_state(); } @@ -413,13 +429,6 @@ void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) { area->set_ray_pickable(p_enable); } -bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); - ERR_FAIL_COND_V(!area, false); - - return area->is_ray_pickable(); -} - void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -429,14 +438,8 @@ void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec /* BODY API */ -RID PhysicsServer3DSW::body_create(BodyMode p_mode, bool p_init_sleeping) { +RID PhysicsServer3DSW::body_create() { Body3DSW *body = memnew(Body3DSW); - if (p_mode != BODY_MODE_RIGID) { - body->set_mode(p_mode); - } - if (p_init_sleeping) { - body->set_state(BODY_STATE_SLEEPING, p_init_sleeping); - } RID rid = body_owner.make_rid(body); body->set_self(rid); return rid; @@ -857,12 +860,6 @@ void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) { body->set_ray_pickable(p_enable); } -bool PhysicsServer3DSW::body_is_ray_pickable(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, false); - return body->is_ray_pickable(); -} - bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); @@ -886,6 +883,8 @@ int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_t } PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { + ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); + Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, nullptr); ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); @@ -896,30 +895,52 @@ PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { /* JOINT API */ -RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { +RID PhysicsServer3DSW::joint_create() { + Joint3DSW *joint = memnew(Joint3DSW); + RID rid = joint_owner.make_rid(joint); + joint->set_self(rid); + return rid; +} + +void PhysicsServer3DSW::joint_clear(RID p_joint) { + Joint3DSW *joint = joint_owner.getornull(p_joint); + if (joint->get_type() != JOINT_TYPE_MAX) { + Joint3DSW *empty_joint = memnew(Joint3DSW); + empty_joint->copy_settings_from(joint); + + joint_owner.replace(p_joint, empty_joint); + memdelete(joint); + } +} + +void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(PinJoint3DSW(body_A, p_local_A, body_B, p_local_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_param(p_param, p_value); } @@ -927,7 +948,7 @@ void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); return pin_joint->get_param(p_param); } @@ -935,7 +956,7 @@ real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_pos_a(p_A); } @@ -943,7 +964,7 @@ void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); return pin_joint->get_position_a(); } @@ -951,7 +972,7 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_PIN); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_pos_b(p_B); } @@ -959,55 +980,63 @@ void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); - ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); return pin_joint->get_position_b(); } -RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) { +void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_frame_A, p_frame_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } -RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { +void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + ERR_FAIL_COND(body_A == body_B); + + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); hinge_joint->set_param(p_param, p_value); } @@ -1015,7 +1044,7 @@ void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_par real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); return hinge_joint->get_param(p_param); } @@ -1023,7 +1052,7 @@ real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_p void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); hinge_joint->set_flag(p_flag, p_value); } @@ -1031,7 +1060,7 @@ void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); return hinge_joint->get_flag(p_flag); } @@ -1077,34 +1106,38 @@ bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); - ERR_FAIL_COND_V(!joint, JOINT_PIN); + ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); } -RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + ERR_FAIL_COND(body_A == body_B); + + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(SliderJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); slider_joint->set_param(p_param, p_value); } @@ -1112,35 +1145,39 @@ void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_p real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); return slider_joint->get_param(p_param); } -RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(ConeTwistJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); cone_twist_joint->set_param(p_param, p_value); } @@ -1148,43 +1185,47 @@ void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointPa real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); return cone_twist_joint->get_param(p_param); } -RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { +void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { Body3DSW *body_A = body_owner.getornull(p_body_A); - ERR_FAIL_COND_V(!body_A, RID()); + ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { - ERR_FAIL_COND_V(!body_A->get_space(), RID()); + ERR_FAIL_COND(!body_A->get_space()); p_body_B = body_A->get_space()->get_static_global_body(); } Body3DSW *body_B = body_owner.getornull(p_body_B); - ERR_FAIL_COND_V(!body_B, RID()); + ERR_FAIL_COND(!body_B); + + ERR_FAIL_COND(body_A == body_B); - ERR_FAIL_COND_V(body_A == body_B, RID()); + Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(Generic6DOFJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B, true)); - RID rid = joint_owner.make_rid(joint); - joint->set_self(rid); - return rid; + + joint->copy_settings_from(prev_joint); + joint_owner.replace(p_joint, joint); + memdelete(prev_joint); } void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); generic_6dof_joint->set_param(p_axis, p_param, p_value); } -real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { +real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); return generic_6dof_joint->get_param(p_axis, p_param); } @@ -1192,15 +1233,15 @@ real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axi void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); - ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); + ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); } -bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { +bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); - ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); + ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); return generic_6dof_joint->get_flag(p_axis, p_flag); } @@ -1317,6 +1358,10 @@ void PhysicsServer3DSW::step(real_t p_step) { #endif } +void PhysicsServer3DSW::sync() { + doing_sync = true; +}; + void PhysicsServer3DSW::flush_queries() { #ifndef _3D_DISABLED @@ -1370,6 +1415,10 @@ void PhysicsServer3DSW::flush_queries() { #endif }; +void PhysicsServer3DSW::end_sync() { + doing_sync = false; +}; + void PhysicsServer3DSW::finish() { memdelete(stepper); memdelete(direct_state); @@ -1431,14 +1480,15 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 & } } -PhysicsServer3DSW *PhysicsServer3DSW::singleton = nullptr; -PhysicsServer3DSW::PhysicsServer3DSW() { - singleton = this; +PhysicsServer3DSW *PhysicsServer3DSW::singletonsw = nullptr; +PhysicsServer3DSW::PhysicsServer3DSW(bool p_using_threads) { + singletonsw = this; BroadPhase3DSW::create_func = BroadPhaseOctree::_create; island_count = 0; active_objects = 0; collision_pairs = 0; - + using_threads = p_using_threads; active = true; flushing_queries = false; + doing_sync = false; }; diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index c48db81d97..afda161fa8 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -50,6 +50,8 @@ class PhysicsServer3DSW : public PhysicsServer3D { int active_objects; int collision_pairs; + bool using_threads; + bool doing_sync; bool flushing_queries; Step3DSW *stepper; @@ -57,20 +59,20 @@ class PhysicsServer3DSW : public PhysicsServer3D { PhysicsDirectBodyState3DSW *direct_state; - mutable RID_PtrOwner<Shape3DSW> shape_owner; - mutable RID_PtrOwner<Space3DSW> space_owner; - mutable RID_PtrOwner<Area3DSW> area_owner; - mutable RID_PtrOwner<Body3DSW> body_owner; - mutable RID_PtrOwner<Joint3DSW> joint_owner; + mutable RID_PtrOwner<Shape3DSW, true> shape_owner; + mutable RID_PtrOwner<Space3DSW, true> space_owner; + mutable RID_PtrOwner<Area3DSW, true> area_owner; + mutable RID_PtrOwner<Body3DSW, true> body_owner; + mutable RID_PtrOwner<Joint3DSW, true> joint_owner; //void _clear_query(QuerySW *p_query); friend class CollisionObject3DSW; SelfList<CollisionObject3DSW>::List pending_shape_update_list; void _update_shapes(); -public: - static PhysicsServer3DSW *singleton; + static PhysicsServer3DSW *singletonsw; +public: struct CollCbkData { int max; int amount; @@ -79,7 +81,17 @@ public: static void _shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata); - virtual RID shape_create(ShapeType p_shape) override; + virtual RID plane_shape_create() override; + virtual RID ray_shape_create() override; + virtual RID sphere_shape_create() override; + virtual RID box_shape_create() override; + virtual RID capsule_shape_create() override; + virtual RID cylinder_shape_create() override; + virtual RID convex_polygon_shape_create() override; + virtual RID concave_polygon_shape_create() override; + virtual RID heightmap_shape_create() override; + virtual RID custom_shape_create() override; + virtual void shape_set_data(RID p_shape, const Variant &p_data) override; virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) override; @@ -140,7 +152,6 @@ public: virtual Transform area_get_transform(RID p_area) const override; virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; - virtual bool area_is_ray_pickable(RID p_area) const override; virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; @@ -153,7 +164,7 @@ public: /* BODY API */ // create a body of a given type - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) override; + virtual RID body_create() override; virtual void body_set_space(RID p_body, RID p_space) override; virtual RID body_get_space(RID p_body) const override; @@ -232,7 +243,6 @@ public: virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant()) override; virtual void body_set_ray_pickable(RID p_body, bool p_enable) override; - virtual bool body_is_ray_pickable(RID p_body) const override; virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override; virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override; @@ -242,7 +252,7 @@ public: /* SOFT BODY */ - virtual RID soft_body_create(bool p_init_sleeping = false) override { return RID(); } + virtual RID soft_body_create() override { return RID(); } virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) override {} @@ -266,49 +276,52 @@ public: virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const override { return Vector3(); } virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override {} - virtual bool soft_body_is_ray_pickable(RID p_body) const override { return false; } virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) override {} - virtual int soft_body_get_simulation_precision(RID p_body) override { return 0; } + virtual int soft_body_get_simulation_precision(RID p_body) const override { return 0; } virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) override {} - virtual real_t soft_body_get_total_mass(RID p_body) override { return 0.; } + virtual real_t soft_body_get_total_mass(RID p_body) const override { return 0.; } virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override {} - virtual real_t soft_body_get_linear_stiffness(RID p_body) override { return 0.; } + virtual real_t soft_body_get_linear_stiffness(RID p_body) const override { return 0.; } - virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override {} - virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override { return 0.; } + virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override {} + virtual real_t soft_body_get_angular_stiffness(RID p_body) const override { return 0.; } virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override {} - virtual real_t soft_body_get_volume_stiffness(RID p_body) override { return 0.; } + virtual real_t soft_body_get_volume_stiffness(RID p_body) const override { return 0.; } virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override {} - virtual real_t soft_body_get_pressure_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) override {} - virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) override {} - virtual real_t soft_body_get_damping_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_damping_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override {} - virtual real_t soft_body_get_drag_coefficient(RID p_body) override { return 0.; } + virtual real_t soft_body_get_drag_coefficient(RID p_body) const override { return 0.; } virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) override {} virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) override {} - virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) override { return Vector3(); } + virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const override { return Vector3(); } virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const override { return Vector3(); } virtual void soft_body_remove_all_pinned_points(RID p_body) override {} virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) override {} - virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) override { return false; } + virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const override { return false; } /* JOINT API */ - virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; + virtual RID joint_create() override; + + virtual void joint_clear(RID p_joint) override; //resets type + + virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override; virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override; virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override; @@ -319,8 +332,8 @@ public: virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override; virtual Vector3 pin_joint_get_local_b(RID p_joint) const override; - virtual RID joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override; - virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override; + virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override; virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override; @@ -328,23 +341,23 @@ public: virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override; virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override; - virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override; - virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override; - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) override; - virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) override; + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const override; virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) override; - virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) override; + virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const override; virtual JointType joint_get_type(RID p_joint) const override; @@ -361,14 +374,16 @@ public: virtual void set_active(bool p_active) override; virtual void init() override; virtual void step(real_t p_step) override; + virtual void sync() override; virtual void flush_queries() override; + virtual void end_sync() override; virtual void finish() override; virtual bool is_flushing_queries() const override { return flushing_queries; } int get_process_info(ProcessInfo p_info) override; - PhysicsServer3DSW(); + PhysicsServer3DSW(bool p_using_threads = false); ~PhysicsServer3DSW() {} }; diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.cpp b/servers/physics_3d/physics_server_3d_wrap_mt.cpp new file mode 100644 index 0000000000..f73f67a756 --- /dev/null +++ b/servers/physics_3d/physics_server_3d_wrap_mt.cpp @@ -0,0 +1,140 @@ +/*************************************************************************/ +/* physics_server_3d_wrap_mt.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 "physics_server_3d_wrap_mt.h" + +#include "core/os/os.h" + +void PhysicsServer3DWrapMT::thread_exit() { + exit = true; +} + +void PhysicsServer3DWrapMT::thread_step(real_t p_delta) { + physics_3d_server->step(p_delta); + step_sem.post(); +} + +void PhysicsServer3DWrapMT::_thread_callback(void *_instance) { + PhysicsServer3DWrapMT *vsmt = reinterpret_cast<PhysicsServer3DWrapMT *>(_instance); + + vsmt->thread_loop(); +} + +void PhysicsServer3DWrapMT::thread_loop() { + server_thread = Thread::get_caller_id(); + + physics_3d_server->init(); + + exit = false; + step_thread_up = true; + while (!exit) { + // flush commands one by one, until exit is requested + command_queue.wait_and_flush_one(); + } + + command_queue.flush_all(); // flush all + + physics_3d_server->finish(); +} + +/* EVENT QUEUING */ + +void PhysicsServer3DWrapMT::step(real_t p_step) { + if (create_thread) { + command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step); + } else { + command_queue.flush_all(); //flush all pending from other threads + physics_3d_server->step(p_step); + } +} + +void PhysicsServer3DWrapMT::sync() { + if (create_thread) { + if (first_frame) { + first_frame = false; + } else { + step_sem.wait(); //must not wait if a step was not issued + } + } + physics_3d_server->sync(); +} + +void PhysicsServer3DWrapMT::flush_queries() { + physics_3d_server->flush_queries(); +} + +void PhysicsServer3DWrapMT::end_sync() { + physics_3d_server->end_sync(); +} + +void PhysicsServer3DWrapMT::init() { + if (create_thread) { + //OS::get_singleton()->release_rendering_thread(); + thread.start(_thread_callback, this); + while (!step_thread_up) { + OS::get_singleton()->delay_usec(1000); + } + } else { + physics_3d_server->init(); + } +} + +void PhysicsServer3DWrapMT::finish() { + if (thread.is_started()) { + command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit); + thread.wait_to_finish(); + } else { + physics_3d_server->finish(); + } +} + +PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) : + command_queue(p_create_thread) { + physics_3d_server = p_contained; + create_thread = p_create_thread; + step_pending = 0; + step_thread_up = false; + + pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); + + if (!p_create_thread) { + server_thread = Thread::get_caller_id(); + } else { + server_thread = 0; + } + + main_thread = Thread::get_caller_id(); + first_frame = true; +} + +PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() { + memdelete(physics_3d_server); + //finish(); +} diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h new file mode 100644 index 0000000000..f60e1332d5 --- /dev/null +++ b/servers/physics_3d/physics_server_3d_wrap_mt.h @@ -0,0 +1,422 @@ +/*************************************************************************/ +/* physics_server_3d_wrap_mt.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 PHYSICS3DSERVERWRAPMT_H +#define PHYSICS3DSERVERWRAPMT_H + +#include "core/config/project_settings.h" +#include "core/os/thread.h" +#include "core/templates/command_queue_mt.h" +#include "servers/physics_server_3d.h" + +#ifdef DEBUG_SYNC +#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); +#else +#define SYNC_DEBUG +#endif + +class PhysicsServer3DWrapMT : public PhysicsServer3D { + mutable PhysicsServer3D *physics_3d_server; + + mutable CommandQueueMT command_queue; + + static void _thread_callback(void *_instance); + void thread_loop(); + + Thread::ID server_thread; + Thread::ID main_thread; + volatile bool exit = false; + Thread thread; + volatile bool step_thread_up = false; + bool create_thread = false; + + Semaphore step_sem; + int step_pending; + void thread_step(real_t p_delta); + void thread_flush(); + + void thread_exit(); + + bool first_frame = true; + + Mutex alloc_mutex; + int pool_max_size = 0; + +public: +#define ServerName PhysicsServer3D +#define ServerNameWrapMT PhysicsServer3DWrapMT +#define server_name physics_3d_server +#define WRITE_ACTION + +#include "servers/server_wrap_mt_common.h" + + //FUNC1RID(shape,ShapeType); todo fix + FUNCRID(plane_shape) + FUNCRID(ray_shape) + FUNCRID(sphere_shape) + FUNCRID(box_shape) + FUNCRID(capsule_shape) + FUNCRID(cylinder_shape) + FUNCRID(convex_polygon_shape) + FUNCRID(concave_polygon_shape) + FUNCRID(heightmap_shape) + FUNCRID(custom_shape) + + FUNC2(shape_set_data, RID, const Variant &); + FUNC2(shape_set_custom_solver_bias, RID, real_t); + + FUNC2(shape_set_margin, RID, real_t) + FUNC1RC(real_t, shape_get_margin, RID) + + FUNC1RC(ShapeType, shape_get_type, RID); + FUNC1RC(Variant, shape_get_data, RID); + FUNC1RC(real_t, shape_get_custom_solver_bias, RID); +#if 0 + //these work well, but should be used from the main thread only + bool shape_collide(RID p_shape_A, const Transform &p_xform_A, const Vector3 &p_motion_A, RID p_shape_B, const Transform &p_xform_B, const Vector3 &p_motion_B, Vector3 *r_results, int p_result_max, int &r_result_count) { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_3d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count); + } +#endif + /* SPACE API */ + + FUNCRID(space); + FUNC2(space_set_active, RID, bool); + FUNC1RC(bool, space_is_active, RID); + + FUNC3(space_set_param, RID, SpaceParameter, real_t); + FUNC2RC(real_t, space_get_param, RID, SpaceParameter); + + // this function only works on physics process, errors and returns null otherwise + PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); + return physics_3d_server->space_get_direct_state(p_space); + } + + FUNC2(space_set_debug_contacts, RID, int); + virtual Vector<Vector3> space_get_contacts(RID p_space) const override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector3>()); + return physics_3d_server->space_get_contacts(p_space); + } + + virtual int space_get_contact_count(RID p_space) const override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0); + return physics_3d_server->space_get_contact_count(p_space); + } + + /* AREA API */ + + //FUNC0RID(area); + FUNCRID(area); + + FUNC2(area_set_space, RID, RID); + FUNC1RC(RID, area_get_space, RID); + + FUNC2(area_set_space_override_mode, RID, AreaSpaceOverrideMode); + FUNC1RC(AreaSpaceOverrideMode, area_get_space_override_mode, RID); + + FUNC4(area_add_shape, RID, RID, const Transform &, bool); + FUNC3(area_set_shape, RID, int, RID); + FUNC3(area_set_shape_transform, RID, int, const Transform &); + FUNC3(area_set_shape_disabled, RID, int, bool); + + FUNC1RC(int, area_get_shape_count, RID); + FUNC2RC(RID, area_get_shape, RID, int); + FUNC2RC(Transform, area_get_shape_transform, RID, int); + FUNC2(area_remove_shape, RID, int); + FUNC1(area_clear_shapes, RID); + + FUNC2(area_attach_object_instance_id, RID, ObjectID); + FUNC1RC(ObjectID, area_get_object_instance_id, RID); + + FUNC3(area_set_param, RID, AreaParameter, const Variant &); + FUNC2(area_set_transform, RID, const Transform &); + + FUNC2RC(Variant, area_get_param, RID, AreaParameter); + FUNC1RC(Transform, area_get_transform, RID); + + FUNC2(area_set_collision_mask, RID, uint32_t); + FUNC2(area_set_collision_layer, RID, uint32_t); + + FUNC2(area_set_monitorable, RID, bool); + FUNC2(area_set_ray_pickable, RID, bool); + + FUNC3(area_set_monitor_callback, RID, Object *, const StringName &); + FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &); + + /* BODY API */ + + //FUNC2RID(body,BodyMode,bool); + FUNCRID(body) + + FUNC2(body_set_space, RID, RID); + FUNC1RC(RID, body_get_space, RID); + + FUNC2(body_set_mode, RID, BodyMode); + FUNC1RC(BodyMode, body_get_mode, RID); + + FUNC4(body_add_shape, RID, RID, const Transform &, bool); + FUNC3(body_set_shape, RID, int, RID); + FUNC3(body_set_shape_transform, RID, int, const Transform &); + + FUNC1RC(int, body_get_shape_count, RID); + FUNC2RC(Transform, body_get_shape_transform, RID, int); + FUNC2RC(RID, body_get_shape, RID, int); + + FUNC3(body_set_shape_disabled, RID, int, bool); + + FUNC2(body_remove_shape, RID, int); + FUNC1(body_clear_shapes, RID); + + FUNC2(body_attach_object_instance_id, RID, ObjectID); + FUNC1RC(ObjectID, body_get_object_instance_id, RID); + + FUNC2(body_set_enable_continuous_collision_detection, RID, bool); + FUNC1RC(bool, body_is_continuous_collision_detection_enabled, RID); + + FUNC2(body_set_collision_layer, RID, uint32_t); + FUNC1RC(uint32_t, body_get_collision_layer, RID); + + FUNC2(body_set_collision_mask, RID, uint32_t); + FUNC1RC(uint32_t, body_get_collision_mask, RID); + + FUNC2(body_set_user_flags, RID, uint32_t); + FUNC1RC(uint32_t, body_get_user_flags, RID); + + FUNC3(body_set_param, RID, BodyParameter, real_t); + FUNC2RC(real_t, body_get_param, RID, BodyParameter); + + FUNC2(body_set_kinematic_safe_margin, RID, real_t); + FUNC1RC(real_t, body_get_kinematic_safe_margin, RID); + + FUNC3(body_set_state, RID, BodyState, const Variant &); + FUNC2RC(Variant, body_get_state, RID, BodyState); + + FUNC2(body_set_applied_force, RID, const Vector3 &); + FUNC1RC(Vector3, body_get_applied_force, RID); + + FUNC2(body_set_applied_torque, RID, const Vector3 &); + FUNC1RC(Vector3, body_get_applied_torque, RID); + + FUNC2(body_add_central_force, RID, const Vector3 &); + FUNC3(body_add_force, RID, const Vector3 &, const Vector3 &); + FUNC2(body_add_torque, RID, const Vector3 &); + FUNC2(body_apply_torque_impulse, RID, const Vector3 &); + FUNC2(body_apply_central_impulse, RID, const Vector3 &); + FUNC3(body_apply_impulse, RID, const Vector3 &, const Vector3 &); + FUNC2(body_set_axis_velocity, RID, const Vector3 &); + + FUNC3(body_set_axis_lock, RID, BodyAxis, bool); + FUNC2RC(bool, body_is_axis_locked, RID, BodyAxis); + + FUNC2(body_add_collision_exception, RID, RID); + FUNC2(body_remove_collision_exception, RID, RID); + FUNC2S(body_get_collision_exceptions, RID, List<RID> *); + + FUNC2(body_set_max_contacts_reported, RID, int); + FUNC1RC(int, body_get_max_contacts_reported, RID); + + FUNC2(body_set_contacts_reported_depth_threshold, RID, real_t); + FUNC1RC(real_t, body_get_contacts_reported_depth_threshold, RID); + + FUNC2(body_set_omit_force_integration, RID, bool); + FUNC1RC(bool, body_is_omitting_force_integration, RID); + + FUNC4(body_set_force_integration_callback, RID, Object *, const StringName &, const Variant &); + + FUNC2(body_set_ray_pickable, RID, bool); + + bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes); + } + + int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); + return physics_3d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); + } + + // this function only works on physics process, errors and returns null otherwise + PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override { + ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); + return physics_3d_server->body_get_direct_state(p_body); + } + + /* SOFT BODY API */ + + FUNCRID(soft_body) + + FUNC2(soft_body_update_rendering_server, RID, class SoftBodyRenderingServerHandler *) + + FUNC2(soft_body_set_space, RID, RID) + FUNC1RC(RID, soft_body_get_space, RID) + + FUNC2(soft_body_set_ray_pickable, RID, bool); + + FUNC2(soft_body_set_collision_layer, RID, uint32_t) + FUNC1RC(uint32_t, soft_body_get_collision_layer, RID) + + FUNC2(soft_body_set_collision_mask, RID, uint32_t) + FUNC1RC(uint32_t, soft_body_get_collision_mask, RID) + + FUNC2(soft_body_add_collision_exception, RID, RID) + FUNC2(soft_body_remove_collision_exception, RID, RID) + FUNC2S(soft_body_get_collision_exceptions, RID, List<RID> *) + + FUNC3(soft_body_set_state, RID, BodyState, const Variant &); + FUNC2RC(Variant, soft_body_get_state, RID, BodyState); + + FUNC2(soft_body_set_transform, RID, const Transform &); + FUNC2RC(Vector3, soft_body_get_vertex_position, RID, int); + + FUNC2(soft_body_set_simulation_precision, RID, int); + FUNC1RC(int, soft_body_get_simulation_precision, RID); + + FUNC2(soft_body_set_total_mass, RID, real_t); + FUNC1RC(real_t, soft_body_get_total_mass, RID); + + FUNC2(soft_body_set_linear_stiffness, RID, real_t); + FUNC1RC(real_t, soft_body_get_linear_stiffness, RID); + + FUNC2(soft_body_set_angular_stiffness, RID, real_t); + FUNC1RC(real_t, soft_body_get_angular_stiffness, RID); + + FUNC2(soft_body_set_volume_stiffness, RID, real_t); + FUNC1RC(real_t, soft_body_get_volume_stiffness, RID); + + FUNC2(soft_body_set_pressure_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_pressure_coefficient, RID); + + FUNC2(soft_body_set_pose_matching_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_pose_matching_coefficient, RID); + + FUNC2(soft_body_set_damping_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_damping_coefficient, RID); + + FUNC2(soft_body_set_drag_coefficient, RID, real_t); + FUNC1RC(real_t, soft_body_get_drag_coefficient, RID); + + FUNC2(soft_body_set_mesh, RID, const REF &); + + FUNC3(soft_body_move_point, RID, int, const Vector3 &); + FUNC2RC(Vector3, soft_body_get_point_global_position, RID, int); + FUNC2RC(Vector3, soft_body_get_point_offset, RID, int); + + FUNC1(soft_body_remove_all_pinned_points, RID); + FUNC3(soft_body_pin_point, RID, int, bool); + FUNC2RC(bool, soft_body_is_point_pinned, RID, int); + + /* JOINT API */ + + FUNCRID(joint) + + FUNC1(joint_clear, RID) + + FUNC5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &) + + FUNC3(pin_joint_set_param, RID, PinJointParam, real_t) + FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam) + + FUNC2(pin_joint_set_local_a, RID, const Vector3 &) + FUNC1RC(Vector3, pin_joint_get_local_a, RID) + + FUNC2(pin_joint_set_local_b, RID, const Vector3 &) + FUNC1RC(Vector3, pin_joint_get_local_b, RID) + + FUNC5(joint_make_hinge, RID, RID, const Transform &, RID, const Transform &) + FUNC7(joint_make_hinge_simple, RID, RID, const Vector3 &, const Vector3 &, RID, const Vector3 &, const Vector3 &) + + FUNC3(hinge_joint_set_param, RID, HingeJointParam, real_t) + FUNC2RC(real_t, hinge_joint_get_param, RID, HingeJointParam) + + FUNC3(hinge_joint_set_flag, RID, HingeJointFlag, bool) + FUNC2RC(bool, hinge_joint_get_flag, RID, HingeJointFlag) + + FUNC5(joint_make_slider, RID, RID, const Transform &, RID, const Transform &) + + FUNC3(slider_joint_set_param, RID, SliderJointParam, real_t) + FUNC2RC(real_t, slider_joint_get_param, RID, SliderJointParam) + + FUNC5(joint_make_cone_twist, RID, RID, const Transform &, RID, const Transform &) + + FUNC3(cone_twist_joint_set_param, RID, ConeTwistJointParam, real_t) + FUNC2RC(real_t, cone_twist_joint_get_param, RID, ConeTwistJointParam) + + FUNC5(joint_make_generic_6dof, RID, RID, const Transform &, RID, const Transform &) + + FUNC4(generic_6dof_joint_set_param, RID, Vector3::Axis, G6DOFJointAxisParam, real_t) + FUNC3RC(real_t, generic_6dof_joint_get_param, RID, Vector3::Axis, G6DOFJointAxisParam) + + FUNC4(generic_6dof_joint_set_flag, RID, Vector3::Axis, G6DOFJointAxisFlag, bool) + FUNC3RC(bool, generic_6dof_joint_get_flag, RID, Vector3::Axis, G6DOFJointAxisFlag) + + FUNC1RC(JointType, joint_get_type, RID); + + FUNC2(joint_set_solver_priority, RID, int); + FUNC1RC(int, joint_get_solver_priority, RID); + + FUNC2(joint_disable_collisions_between_bodies, RID, const bool); + FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID); + + /* MISC */ + + FUNC1(free, RID); + FUNC1(set_active, bool); + + virtual void init() override; + virtual void step(real_t p_step) override; + virtual void sync() override; + virtual void end_sync() override; + virtual void flush_queries() override; + virtual void finish() override; + + virtual bool is_flushing_queries() const override { + return physics_3d_server->is_flushing_queries(); + } + + int get_process_info(ProcessInfo p_info) override { + return physics_3d_server->get_process_info(p_info); + } + + PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread); + ~PhysicsServer3DWrapMT(); + +#undef ServerNameWrapMT +#undef ServerName +#undef server_name +#undef WRITE_ACTION +}; + +#ifdef DEBUG_SYNC +#undef DEBUG_SYNC +#endif +#undef SYNC_DEBUG + +#endif // PHYSICS3DSERVERWRAPMT_H diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index 9c37060bea..5bac4f19b9 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -34,10 +34,12 @@ #include "core/math/quick_hull.h" #include "core/templates/sort_array.h" -#define _POINT_SNAP 0.001953125 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002 #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.9998 +#define _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD 0.002 +#define _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD 0.999 + void Shape3DSW::configure(const AABB &p_aabb) { aabb = p_aabb; configured = true; @@ -50,7 +52,8 @@ void Shape3DSW::configure(const AABB &p_aabb) { Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const { Vector3 res; int amnt; - get_supports(p_normal, 1, &res, amnt); + FeatureType type; + get_supports(p_normal, 1, &res, amnt, type); return res; } @@ -167,16 +170,19 @@ Vector3 RayShape3DSW::get_support(const Vector3 &p_normal) const { } } -void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = Vector3(0, 0, 0); r_supports[1] = Vector3(0, 0, length); } else if (p_normal.z > 0) { r_amount = 1; + r_type = FEATURE_POINT; *r_supports = Vector3(0, 0, length); } else { r_amount = 1; + r_type = FEATURE_POINT; *r_supports = Vector3(0, 0, 0); } } @@ -246,9 +252,10 @@ Vector3 SphereShape3DSW::get_support(const Vector3 &p_normal) const { return p_normal * radius; } -void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { *r_supports = p_normal * radius; r_amount = 1; + r_type = FEATURE_POINT; } bool SphereShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { @@ -312,7 +319,7 @@ Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const { return point; } -void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { static const int next[3] = { 1, 2, 0 }; static const int next2[3] = { 2, 0, 1 }; @@ -325,6 +332,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s bool neg = dot < 0; r_amount = 4; + r_type = FEATURE_FACE; Vector3 point; point[i] = half_extents[i]; @@ -362,6 +370,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; + r_type = FEATURE_EDGE; int i_n = next[i]; int i_n2 = next2[i]; @@ -389,6 +398,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s (p_normal.z < 0) ? -half_extents.z : half_extents.z); r_amount = 1; + r_type = FEATURE_POINT; r_supports[0] = point; } @@ -500,7 +510,7 @@ Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const { return n; } -void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { Vector3 n = p_normal; real_t d = n.z; @@ -512,6 +522,7 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 n *= radius; r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = n; r_supports[0].z += height * 0.5; r_supports[1] = n; @@ -523,6 +534,7 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 n *= radius; n.z += h * 0.5; r_amount = 1; + r_type = FEATURE_POINT; *r_supports = n; } } @@ -642,6 +654,186 @@ CapsuleShape3DSW::CapsuleShape3DSW() { height = radius = 0; } +/********** CYLINDER *************/ + +void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { + Vector3 cylinder_axis = p_transform.basis.get_axis(1).normalized(); + real_t axis_dot = cylinder_axis.dot(p_normal); + + Vector3 local_normal = p_transform.basis.xform_inv(p_normal); + real_t scale = local_normal.length(); + real_t scaled_radius = radius * scale; + real_t scaled_height = height * scale; + + real_t length; + if (Math::abs(axis_dot) > 1.0) { + length = scaled_height * 0.5; + } else { + length = Math::abs(axis_dot * scaled_height * 0.5) + scaled_radius * Math::sqrt(1.0 - axis_dot * axis_dot); + } + + real_t distance = p_normal.dot(p_transform.origin); + + r_min = distance - length; + r_max = distance + length; +} + +Vector3 CylinderShape3DSW::get_support(const Vector3 &p_normal) const { + Vector3 n = p_normal; + real_t h = (n.y > 0) ? height : -height; + real_t s = Math::sqrt(n.x * n.x + n.z * n.z); + if (Math::is_zero_approx(s)) { + n.x = radius; + n.y = h * 0.5; + n.z = 0.0; + } else { + real_t d = radius / s; + n.x = n.x * d; + n.y = h * 0.5; + n.z = n.z * d; + } + + return n; +} + +void CylinderShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { + real_t d = p_normal.y; + if (Math::abs(d) > _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD) { + real_t h = (d > 0) ? height : -height; + + Vector3 n = p_normal; + n.x = 0.0; + n.z = 0.0; + n.y = h * 0.5; + + r_amount = 3; + r_type = FEATURE_CIRCLE; + r_supports[0] = n; + r_supports[1] = n; + r_supports[1].x += radius; + r_supports[2] = n; + r_supports[2].z += radius; + } else if (Math::abs(d) < _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD) { + // make it flat + Vector3 n = p_normal; + n.y = 0.0; + n.normalize(); + n *= radius; + + r_amount = 2; + r_type = FEATURE_EDGE; + r_supports[0] = n; + r_supports[0].y += height * 0.5; + r_supports[1] = n; + r_supports[1].y -= height * 0.5; + } else { + r_amount = 1; + r_type = FEATURE_POINT; + r_supports[0] = get_support(p_normal); + return; + + Vector3 n = p_normal; + real_t h = n.y * Math::sqrt(0.25 * height * height + radius * radius); + if (Math::abs(h) > 1.0) { + // Top or bottom surface. + n.y = (n.y > 0.0) ? height * 0.5 : -height * 0.5; + } else { + // Lateral surface. + n.y = height * 0.5 * h; + } + + real_t s = Math::sqrt(n.x * n.x + n.z * n.z); + if (Math::is_zero_approx(s)) { + n.x = 0.0; + n.z = 0.0; + } else { + real_t scaled_radius = radius / s; + n.x = n.x * scaled_radius; + n.z = n.z * scaled_radius; + } + + r_supports[0] = n; + } +} + +bool CylinderShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { + return Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &r_result, &r_normal, 1); +} + +bool CylinderShape3DSW::intersect_point(const Vector3 &p_point) const { + if (Math::abs(p_point.y) < height * 0.5) { + return Vector3(p_point.x, 0, p_point.z).length() < radius; + } + return false; +} + +Vector3 CylinderShape3DSW::get_closest_point_to(const Vector3 &p_point) const { + if (Math::absf(p_point.y) > height * 0.5) { + // Project point to top disk. + real_t dir = p_point.y > 0.0 ? 1.0 : -1.0; + Vector3 circle_pos(0.0, dir * height * 0.5, 0.0); + Plane circle_plane(circle_pos, Vector3(0.0, dir, 0.0)); + Vector3 proj_point = circle_plane.project(p_point); + + // Clip position. + Vector3 delta_point_1 = proj_point - circle_pos; + real_t dist_point_1 = delta_point_1.length_squared(); + if (!Math::is_zero_approx(dist_point_1)) { + dist_point_1 = Math::sqrt(dist_point_1); + proj_point = circle_pos + delta_point_1 * MIN(dist_point_1, radius) / dist_point_1; + } + + return proj_point; + } else { + Vector3 s[2] = { + Vector3(0, -height * 0.5, 0), + Vector3(0, height * 0.5, 0), + }; + + Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s); + + if (p.distance_to(p_point) < radius) { + return p_point; + } + + return p + (p_point - p).normalized() * radius; + } +} + +Vector3 CylinderShape3DSW::get_moment_of_inertia(real_t p_mass) const { + // use bad AABB approximation + Vector3 extents = get_aabb().size * 0.5; + + return Vector3( + (p_mass / 3.0) * (extents.y * extents.y + extents.z * extents.z), + (p_mass / 3.0) * (extents.x * extents.x + extents.z * extents.z), + (p_mass / 3.0) * (extents.y * extents.y + extents.y * extents.y)); +} + +void CylinderShape3DSW::_setup(real_t p_height, real_t p_radius) { + height = p_height; + radius = p_radius; + configure(AABB(Vector3(-radius, -height * 0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); +} + +void CylinderShape3DSW::set_data(const Variant &p_data) { + Dictionary d = p_data; + ERR_FAIL_COND(!d.has("radius")); + ERR_FAIL_COND(!d.has("height")); + _setup(d["height"], d["radius"]); +} + +Variant CylinderShape3DSW::get_data() const { + Dictionary d; + d["radius"] = radius; + d["height"] = height; + return d; +} + +CylinderShape3DSW::CylinderShape3DSW() { + height = radius = 0; +} + /********** CONVEX POLYGON *************/ void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { @@ -689,7 +881,7 @@ Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const { return vrts[vert_support_idx]; } -void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); @@ -734,6 +926,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve r_supports[j] = vertices[ind[j]]; } r_amount = m; + r_type = FEATURE_FACE; return; } } @@ -743,6 +936,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) { r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = vertices[edges[i].a]; r_supports[1] = vertices[edges[i].b]; return; @@ -751,6 +945,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve r_supports[0] = vertices[vtx]; r_amount = 1; + r_type = FEATURE_POINT; } bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { @@ -935,12 +1130,13 @@ Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const { return vertex[vert_support_idx]; } -void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { +void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { Vector3 n = p_normal; /** TEST FACE AS SUPPORT **/ if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 3; + r_type = FEATURE_FACE; for (int i = 0; i < 3; i++) { r_supports[i] = vertex[i]; } @@ -974,6 +1170,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { r_amount = 2; + r_type = FEATURE_EDGE; r_supports[0] = vertex[i]; r_supports[1] = vertex[nx]; return; @@ -981,6 +1178,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ } r_amount = 1; + r_type = FEATURE_POINT; r_supports[0] = vertex[vert_support_idx]; } diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h index 851c0d9443..cafe978abb 100644 --- a/servers/physics_3d/shape_3d_sw.h +++ b/servers/physics_3d/shape_3d_sw.h @@ -67,8 +67,11 @@ protected: void configure(const AABB &p_aabb); public: - enum { - MAX_SUPPORTS = 8 + enum FeatureType { + FEATURE_POINT, + FEATURE_EDGE, + FEATURE_FACE, + FEATURE_CIRCLE, }; virtual real_t get_area() const { return aabb.get_area(); } @@ -85,7 +88,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const = 0; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const = 0; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0; virtual bool intersect_point(const Vector3 &p_point) const = 0; @@ -110,7 +113,7 @@ class ConcaveShape3DSW : public Shape3DSW { public: virtual bool is_concave() const { return true; } typedef void (*Callback)(void *p_userdata, Shape3DSW *p_convex); - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; @@ -129,7 +132,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_PLANE; } virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; @@ -156,7 +159,7 @@ public: virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_RAY; } virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; @@ -184,7 +187,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -209,7 +212,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -238,7 +241,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -251,6 +254,35 @@ public: CapsuleShape3DSW(); }; +class CylinderShape3DSW : public Shape3DSW { + real_t height; + real_t radius; + + void _setup(real_t p_height, real_t p_radius); + +public: + _FORCE_INLINE_ real_t get_height() const { return height; } + _FORCE_INLINE_ real_t get_radius() const { return radius; } + + virtual real_t get_area() const { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; } + + virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CYLINDER; } + + virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; + virtual Vector3 get_support(const Vector3 &p_normal) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; + virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; + virtual bool intersect_point(const Vector3 &p_point) const; + virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; + + virtual Vector3 get_moment_of_inertia(real_t p_mass) const; + + virtual void set_data(const Variant &p_data); + virtual Variant get_data() const; + + CylinderShape3DSW(); +}; + struct ConvexPolygonShape3DSW : public Shape3DSW { Geometry3D::MeshData mesh; @@ -263,7 +295,7 @@ public: virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; virtual Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -399,7 +431,7 @@ struct FaceShape3DSW : public Shape3DSW { void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; Vector3 get_support(const Vector3 &p_normal) const; - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const; bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; @@ -437,7 +469,7 @@ struct MotionShape3DSW : public Shape3DSW { } return support; } - virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } + virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; } bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; } virtual bool intersect_point(const Vector3 &p_point) const { return false; } virtual Vector3 get_closest_point_to(const Vector3 &p_point) const { return p_point; } diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 547717c73c..40537c7001 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -181,7 +181,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans return 0; } - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_xform.xform(shape->get_aabb()); @@ -232,7 +232,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans } bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); AABB aabb = p_xform.xform(shape->get_aabb()); @@ -340,7 +340,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ return false; } - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_shape_xform.xform(shape->get_aabb()); @@ -412,7 +412,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B, } bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_shape_xform.xform(shape->get_aabb()); @@ -468,9 +468,9 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap } Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - CollisionObject3DSW *obj = PhysicsServer3DSW::singleton->area_owner.getornull(p_object); + CollisionObject3DSW *obj = PhysicsServer3DSW::singletonsw->area_owner.getornull(p_object); if (!obj) { - obj = PhysicsServer3DSW::singleton->body_owner.getornull(p_object); + obj = PhysicsServer3DSW::singletonsw->body_owner.getornull(p_object); } ERR_FAIL_COND_V(!obj, Vector3()); @@ -1211,7 +1211,7 @@ Space3DSW::Space3DSW() { constraint_bias = 0.01; body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_linear", 0.1); - body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI)); + body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg2rad(8.0)); body_time_to_sleep = GLOBAL_DEF("physics/3d/time_before_sleep", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); body_angular_velocity_damp_ratio = 10; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 7c36229e9f..83ebc0c55b 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -655,12 +655,16 @@ void PhysicsServer2D::_bind_methods() { /* JOINT API */ + ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer2D::joint_create); + + ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer2D::joint_clear); + ClassDB::bind_method(D_METHOD("joint_set_param", "joint", "param", "value"), &PhysicsServer2D::joint_set_param); ClassDB::bind_method(D_METHOD("joint_get_param", "joint", "param"), &PhysicsServer2D::joint_get_param); - ClassDB::bind_method(D_METHOD("pin_joint_create", "anchor", "body_a", "body_b"), &PhysicsServer2D::pin_joint_create, DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("groove_joint_create", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::groove_joint_create, DEFVAL(RID()), DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("damped_spring_joint_create", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::damped_spring_joint_create, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("joint_make_pin", "joint", "anchor", "body_a", "body_b"), &PhysicsServer2D::joint_make_pin, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("joint_make_groove", "joint", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_groove, DEFVAL(RID()), DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("joint_make_damped_spring", "joint", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_damped_spring, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("damped_spring_joint_set_param", "joint", "param", "value"), &PhysicsServer2D::damped_spring_joint_set_param); ClassDB::bind_method(D_METHOD("damped_spring_joint_get_param", "joint", "param"), &PhysicsServer2D::damped_spring_joint_get_param); @@ -727,9 +731,10 @@ void PhysicsServer2D::_bind_methods() { BIND_ENUM_CONSTANT(BODY_STATE_SLEEPING); BIND_ENUM_CONSTANT(BODY_STATE_CAN_SLEEP); - BIND_ENUM_CONSTANT(JOINT_PIN); - BIND_ENUM_CONSTANT(JOINT_GROOVE); - BIND_ENUM_CONSTANT(JOINT_DAMPED_SPRING); + BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); + BIND_ENUM_CONSTANT(JOINT_TYPE_GROOVE); + BIND_ENUM_CONSTANT(JOINT_TYPE_DAMPED_SPRING); + BIND_ENUM_CONSTANT(JOINT_TYPE_MAX); BIND_ENUM_CONSTANT(JOINT_PARAM_BIAS); BIND_ENUM_CONSTANT(JOINT_PARAM_MAX_BIAS); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 710eecfdec..28f22ce06b 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -524,10 +524,15 @@ public: /* JOINT API */ + virtual RID joint_create() = 0; + + virtual void joint_clear(RID p_joint) = 0; + enum JointType { - JOINT_PIN, - JOINT_GROOVE, - JOINT_DAMPED_SPRING + JOINT_TYPE_PIN, + JOINT_TYPE_GROOVE, + JOINT_TYPE_DAMPED_SPRING, + JOINT_TYPE_MAX }; enum JointParam { @@ -542,9 +547,9 @@ public: virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0; - virtual RID pin_joint_create(const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0; - virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0; - virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0; + virtual void joint_make_pin(RID p_joint, const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0; + virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0; + virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0; enum PinJointParam { PIN_JOINT_SOFTNESS diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index a4dc80b0a6..8fd0ddbfef 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -398,10 +398,47 @@ void PhysicsShapeQueryResult3D::_bind_methods() { /////////////////////////////////////// +RID PhysicsServer3D::shape_create(ShapeType p_shape) { + switch (p_shape) { + case SHAPE_PLANE: + return plane_shape_create(); + case SHAPE_RAY: + return ray_shape_create(); + case SHAPE_SPHERE: + return sphere_shape_create(); + case SHAPE_BOX: + return box_shape_create(); + case SHAPE_CAPSULE: + return capsule_shape_create(); + case SHAPE_CYLINDER: + return cylinder_shape_create(); + case SHAPE_CONVEX_POLYGON: + return convex_polygon_shape_create(); + case SHAPE_CONCAVE_POLYGON: + return concave_polygon_shape_create(); + case SHAPE_HEIGHTMAP: + return heightmap_shape_create(); + case SHAPE_CUSTOM: + return custom_shape_create(); + default: + return RID(); + } +} + void PhysicsServer3D::_bind_methods() { #ifndef _3D_DISABLED - ClassDB::bind_method(D_METHOD("shape_create", "type"), &PhysicsServer3D::shape_create); + ClassDB::bind_method(D_METHOD("plane_shape_create"), &PhysicsServer3D::plane_shape_create); + ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer3D::ray_shape_create); + ClassDB::bind_method(D_METHOD("sphere_shape_create"), &PhysicsServer3D::sphere_shape_create); + ClassDB::bind_method(D_METHOD("box_shape_create"), &PhysicsServer3D::box_shape_create); + ClassDB::bind_method(D_METHOD("capsule_shape_create"), &PhysicsServer3D::capsule_shape_create); + ClassDB::bind_method(D_METHOD("cylinder_shape_create"), &PhysicsServer3D::cylinder_shape_create); + ClassDB::bind_method(D_METHOD("convex_polygon_shape_create"), &PhysicsServer3D::convex_polygon_shape_create); + ClassDB::bind_method(D_METHOD("concave_polygon_shape_create"), &PhysicsServer3D::concave_polygon_shape_create); + ClassDB::bind_method(D_METHOD("heightmap_shape_create"), &PhysicsServer3D::heightmap_shape_create); + ClassDB::bind_method(D_METHOD("custom_shape_create"), &PhysicsServer3D::custom_shape_create); + ClassDB::bind_method(D_METHOD("shape_set_data", "shape", "data"), &PhysicsServer3D::shape_set_data); ClassDB::bind_method(D_METHOD("shape_get_type", "shape"), &PhysicsServer3D::shape_get_type); @@ -450,9 +487,8 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer3D::area_set_monitorable); ClassDB::bind_method(D_METHOD("area_set_ray_pickable", "area", "enable"), &PhysicsServer3D::area_set_ray_pickable); - ClassDB::bind_method(D_METHOD("area_is_ray_pickable", "area"), &PhysicsServer3D::area_is_ray_pickable); - ClassDB::bind_method(D_METHOD("body_create", "mode", "init_sleeping"), &PhysicsServer3D::body_create, DEFVAL(BODY_MODE_RIGID), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("body_create"), &PhysicsServer3D::body_create); ClassDB::bind_method(D_METHOD("body_set_space", "body", "space"), &PhysicsServer3D::body_set_space); ClassDB::bind_method(D_METHOD("body_get_space", "body"), &PhysicsServer3D::body_get_space); @@ -517,19 +553,22 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "receiver", "method", "userdata"), &PhysicsServer3D::body_set_force_integration_callback, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("body_set_ray_pickable", "body", "enable"), &PhysicsServer3D::body_set_ray_pickable); - ClassDB::bind_method(D_METHOD("body_is_ray_pickable", "body"), &PhysicsServer3D::body_is_ray_pickable); ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer3D::body_get_direct_state); /* JOINT API */ - BIND_ENUM_CONSTANT(JOINT_PIN); - BIND_ENUM_CONSTANT(JOINT_HINGE); - BIND_ENUM_CONSTANT(JOINT_SLIDER); - BIND_ENUM_CONSTANT(JOINT_CONE_TWIST); - BIND_ENUM_CONSTANT(JOINT_6DOF); + ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer3D::joint_create); + ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer3D::joint_clear); + + BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); + BIND_ENUM_CONSTANT(JOINT_TYPE_HINGE); + BIND_ENUM_CONSTANT(JOINT_TYPE_SLIDER); + BIND_ENUM_CONSTANT(JOINT_TYPE_CONE_TWIST); + BIND_ENUM_CONSTANT(JOINT_TYPE_6DOF); + BIND_ENUM_CONSTANT(JOINT_TYPE_MAX); - ClassDB::bind_method(D_METHOD("joint_create_pin", "body_A", "local_A", "body_B", "local_B"), &PhysicsServer3D::joint_create_pin); + ClassDB::bind_method(D_METHOD("joint_make_pin", "joint", "body_A", "local_A", "body_B", "local_B"), &PhysicsServer3D::joint_make_pin); ClassDB::bind_method(D_METHOD("pin_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::pin_joint_set_param); ClassDB::bind_method(D_METHOD("pin_joint_get_param", "joint", "param"), &PhysicsServer3D::pin_joint_get_param); @@ -555,7 +594,7 @@ void PhysicsServer3D::_bind_methods() { BIND_ENUM_CONSTANT(HINGE_JOINT_FLAG_USE_LIMIT); BIND_ENUM_CONSTANT(HINGE_JOINT_FLAG_ENABLE_MOTOR); - ClassDB::bind_method(D_METHOD("joint_create_hinge", "body_A", "hinge_A", "body_B", "hinge_B"), &PhysicsServer3D::joint_create_hinge); + ClassDB::bind_method(D_METHOD("joint_make_hinge", "joint", "body_A", "hinge_A", "body_B", "hinge_B"), &PhysicsServer3D::joint_make_hinge); ClassDB::bind_method(D_METHOD("hinge_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::hinge_joint_set_param); ClassDB::bind_method(D_METHOD("hinge_joint_get_param", "joint", "param"), &PhysicsServer3D::hinge_joint_get_param); @@ -563,7 +602,7 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("hinge_joint_set_flag", "joint", "flag", "enabled"), &PhysicsServer3D::hinge_joint_set_flag); ClassDB::bind_method(D_METHOD("hinge_joint_get_flag", "joint", "flag"), &PhysicsServer3D::hinge_joint_get_flag); - ClassDB::bind_method(D_METHOD("joint_create_slider", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_slider); + ClassDB::bind_method(D_METHOD("joint_make_slider", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_slider); ClassDB::bind_method(D_METHOD("slider_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::slider_joint_set_param); ClassDB::bind_method(D_METHOD("slider_joint_get_param", "joint", "param"), &PhysicsServer3D::slider_joint_get_param); @@ -593,7 +632,7 @@ void PhysicsServer3D::_bind_methods() { BIND_ENUM_CONSTANT(SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING); BIND_ENUM_CONSTANT(SLIDER_JOINT_MAX); - ClassDB::bind_method(D_METHOD("joint_create_cone_twist", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_cone_twist); + ClassDB::bind_method(D_METHOD("joint_make_cone_twist", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_cone_twist); ClassDB::bind_method(D_METHOD("cone_twist_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::cone_twist_joint_set_param); ClassDB::bind_method(D_METHOD("cone_twist_joint_get_param", "joint", "param"), &PhysicsServer3D::cone_twist_joint_get_param); @@ -631,7 +670,7 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("joint_set_solver_priority", "joint", "priority"), &PhysicsServer3D::joint_set_solver_priority); ClassDB::bind_method(D_METHOD("joint_get_solver_priority", "joint"), &PhysicsServer3D::joint_get_solver_priority); - ClassDB::bind_method(D_METHOD("joint_create_generic_6dof", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_generic_6dof); + ClassDB::bind_method(D_METHOD("joint_make_generic_6dof", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_generic_6dof); ClassDB::bind_method(D_METHOD("generic_6dof_joint_set_param", "joint", "axis", "param", "value"), &PhysicsServer3D::generic_6dof_joint_set_param); ClassDB::bind_method(D_METHOD("generic_6dof_joint_get_param", "joint", "axis", "param"), &PhysicsServer3D::generic_6dof_joint_get_param); @@ -718,7 +757,6 @@ void PhysicsServer3D::_bind_methods() { } PhysicsServer3D::PhysicsServer3D() { - ERR_FAIL_COND(singleton != nullptr); singleton = this; } diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 1349e0e033..e16857192c 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -240,7 +240,19 @@ public: SHAPE_CUSTOM, ///< Server-Implementation based custom shape, calling shape_create() with this value will result in an error }; - virtual RID shape_create(ShapeType p_shape) = 0; + RID shape_create(ShapeType p_shape); + + virtual RID plane_shape_create() = 0; + virtual RID ray_shape_create() = 0; + virtual RID sphere_shape_create() = 0; + virtual RID box_shape_create() = 0; + virtual RID capsule_shape_create() = 0; + virtual RID cylinder_shape_create() = 0; + virtual RID convex_polygon_shape_create() = 0; + virtual RID concave_polygon_shape_create() = 0; + virtual RID heightmap_shape_create() = 0; + virtual RID custom_shape_create() = 0; + virtual void shape_set_data(RID p_shape, const Variant &p_data) = 0; virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) = 0; @@ -344,7 +356,6 @@ public: virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0; virtual void area_set_ray_pickable(RID p_area, bool p_enable) = 0; - virtual bool area_is_ray_pickable(RID p_area) const = 0; /* BODY API */ @@ -357,7 +368,7 @@ public: BODY_MODE_CHARACTER }; - virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) = 0; + virtual RID body_create() = 0; virtual void body_set_space(RID p_body, RID p_space) = 0; virtual RID body_get_space(RID p_body) const = 0; @@ -468,7 +479,6 @@ public: virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant()) = 0; virtual void body_set_ray_pickable(RID p_body, bool p_enable) = 0; - virtual bool body_is_ray_pickable(RID p_body) const = 0; // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0; @@ -510,7 +520,7 @@ public: /* SOFT BODY */ - virtual RID soft_body_create(bool p_init_sleeping = false) = 0; + virtual RID soft_body_create() = 0; virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) = 0; @@ -536,55 +546,59 @@ public: virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const = 0; virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) = 0; - virtual bool soft_body_is_ray_pickable(RID p_body) const = 0; virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) = 0; - virtual int soft_body_get_simulation_precision(RID p_body) = 0; + virtual int soft_body_get_simulation_precision(RID p_body) const = 0; virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) = 0; - virtual real_t soft_body_get_total_mass(RID p_body) = 0; + virtual real_t soft_body_get_total_mass(RID p_body) const = 0; virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) = 0; - virtual real_t soft_body_get_linear_stiffness(RID p_body) = 0; + virtual real_t soft_body_get_linear_stiffness(RID p_body) const = 0; - virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) = 0; - virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) = 0; + virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) = 0; + virtual real_t soft_body_get_angular_stiffness(RID p_body) const = 0; virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) = 0; - virtual real_t soft_body_get_volume_stiffness(RID p_body) = 0; + virtual real_t soft_body_get_volume_stiffness(RID p_body) const = 0; virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) = 0; - virtual real_t soft_body_get_pressure_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_pressure_coefficient(RID p_body) const = 0; virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) = 0; - virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) const = 0; virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) = 0; - virtual real_t soft_body_get_damping_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_damping_coefficient(RID p_body) const = 0; virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) = 0; - virtual real_t soft_body_get_drag_coefficient(RID p_body) = 0; + virtual real_t soft_body_get_drag_coefficient(RID p_body) const = 0; virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) = 0; - virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) = 0; + virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const = 0; virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const = 0; virtual void soft_body_remove_all_pinned_points(RID p_body) = 0; virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) = 0; - virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) = 0; + virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const = 0; /* JOINT API */ enum JointType { - JOINT_PIN, - JOINT_HINGE, - JOINT_SLIDER, - JOINT_CONE_TWIST, - JOINT_6DOF + JOINT_TYPE_PIN, + JOINT_TYPE_HINGE, + JOINT_TYPE_SLIDER, + JOINT_TYPE_CONE_TWIST, + JOINT_TYPE_6DOF, + JOINT_TYPE_MAX, }; + virtual RID joint_create() = 0; + + virtual void joint_clear(RID p_joint) = 0; + virtual JointType joint_get_type(RID p_joint) const = 0; virtual void joint_set_solver_priority(RID p_joint, int p_priority) = 0; @@ -593,7 +607,7 @@ public: virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0; - virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0; + virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0; enum PinJointParam { PIN_JOINT_BIAS, @@ -628,8 +642,8 @@ public: HINGE_JOINT_FLAG_MAX }; - virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0; - virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0; + virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0; + virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0; virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) = 0; virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const = 0; @@ -665,7 +679,7 @@ public: }; - virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) = 0; virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const = 0; @@ -679,7 +693,7 @@ public: CONE_TWIST_MAX }; - virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) = 0; virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const = 0; @@ -720,13 +734,13 @@ public: G6DOF_JOINT_FLAG_MAX }; - virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A + virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) = 0; - virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) = 0; + virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const = 0; virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) = 0; - virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) = 0; + virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const = 0; /* QUERY API */ @@ -742,7 +756,9 @@ public: virtual void set_active(bool p_active) = 0; virtual void init() = 0; virtual void step(real_t p_step) = 0; + virtual void sync() = 0; virtual void flush_queries() = 0; + virtual void end_sync() = 0; virtual void finish() = 0; virtual bool is_flushing_queries() const = 0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 58bcdf5802..7478ed15a1 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -36,6 +36,7 @@ #include "audio/audio_effect.h" #include "audio/audio_stream.h" #include "audio/effects/audio_effect_amplify.h" +#include "audio/effects/audio_effect_capture.h" #include "audio/effects/audio_effect_chorus.h" #include "audio/effects/audio_effect_compressor.h" #include "audio/effects/audio_effect_delay.h" @@ -60,6 +61,7 @@ #include "physics_2d/physics_server_2d_sw.h" #include "physics_2d/physics_server_2d_wrap_mt.h" #include "physics_3d/physics_server_3d_sw.h" +#include "physics_3d/physics_server_3d_wrap_mt.h" #include "physics_server_2d.h" #include "physics_server_3d.h" #include "rendering/renderer_compositor.h" @@ -75,11 +77,19 @@ ShaderTypes *shader_types = nullptr; PhysicsServer3D *_createGodotPhysics3DCallback() { - return memnew(PhysicsServer3DSW); + bool using_threads = GLOBAL_GET("physics/3d/run_on_thread"); + + PhysicsServer3D *physics_server = memnew(PhysicsServer3DSW(using_threads)); + + return memnew(PhysicsServer3DWrapMT(physics_server, using_threads)); } PhysicsServer2D *_createGodotPhysics2DCallback() { - return PhysicsServer2DWrapMT::init_server<PhysicsServer2DSW>(); + bool using_threads = GLOBAL_GET("physics/2d/run_on_thread"); + + PhysicsServer2D *physics_server = memnew(PhysicsServer2DSW(using_threads)); + + return memnew(PhysicsServer2DWrapMT(physics_server, using_threads)); } static bool has_server_feature_callback(const String &p_feature) { @@ -166,6 +176,8 @@ void register_server_types() { ClassDB::register_class<AudioEffectRecord>(); ClassDB::register_class<AudioEffectSpectrumAnalyzer>(); ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>(); + + ClassDB::register_class<AudioEffectCapture>(); } ClassDB::register_virtual_class<RenderingDevice>(); diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 2d2847e6ca..e34bc9acb8 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -97,7 +97,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2 } } -void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item> &canvas_item_owner) { +void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item, true> &canvas_item_owner) { do { ysort_owner->ysort_children_count = -1; ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr; @@ -356,12 +356,12 @@ bool RendererCanvasCull::was_sdf_used() { return sdf_used; } -RID RendererCanvasCull::canvas_create() { +RID RendererCanvasCull::canvas_allocate() { + return canvas_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_initialize(RID p_rid) { Canvas *canvas = memnew(Canvas); - ERR_FAIL_COND_V(!canvas, RID()); - RID rid = canvas_owner.make_rid(canvas); - - return rid; + canvas_owner.initialize_rid(p_rid, canvas); } void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { @@ -393,11 +393,12 @@ void RendererCanvasCull::canvas_set_parent(RID p_canvas, RID p_parent, float p_s canvas->parent_scale = p_scale; } -RID RendererCanvasCull::canvas_item_create() { +RID RendererCanvasCull::canvas_item_allocate() { + return canvas_item_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_item_initialize(RID p_rid) { Item *canvas_item = memnew(Item); - ERR_FAIL_COND_V(!canvas_item, RID()); - - return canvas_item_owner.make_rid(canvas_item); + canvas_item_owner.initialize_rid(p_rid, canvas_item); } void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) { @@ -721,8 +722,10 @@ void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, static const int circle_points = 64; points.resize(circle_points); + const real_t circle_point_step = Math_TAU / circle_points; + for (int i = 0; i < circle_points; i++) { - float angle = (i / float(circle_points)) * 2 * Math_PI; + float angle = i * circle_point_step; points.write[i].x = Math::cos(angle) * p_radius; points.write[i].y = Math::sin(angle) * p_radius; points.write[i] += p_pos; @@ -1073,10 +1076,13 @@ void RendererCanvasCull::canvas_item_set_canvas_group_mode(RID p_item, RS::Canva } } -RID RendererCanvasCull::canvas_light_create() { +RID RendererCanvasCull::canvas_light_allocate() { + return canvas_light_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_light_initialize(RID p_rid) { RendererCanvasRender::Light *clight = memnew(RendererCanvasRender::Light); clight->light_internal = RSG::canvas_render->light_create(); - return canvas_light_owner.make_rid(clight); + return canvas_light_owner.initialize_rid(p_rid, clight); } void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { @@ -1266,10 +1272,13 @@ void RendererCanvasCull::canvas_light_set_shadow_smooth(RID p_light, float p_smo clight->shadow_smooth = p_smooth; } -RID RendererCanvasCull::canvas_light_occluder_create() { +RID RendererCanvasCull::canvas_light_occluder_allocate() { + return canvas_light_occluder_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_light_occluder_initialize(RID p_rid) { RendererCanvasRender::LightOccluderInstance *occluder = memnew(RendererCanvasRender::LightOccluderInstance); - return canvas_light_occluder_owner.make_rid(occluder); + return canvas_light_occluder_owner.initialize_rid(p_rid, occluder); } void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { @@ -1347,10 +1356,13 @@ void RendererCanvasCull::canvas_light_occluder_set_light_mask(RID p_occluder, in occluder->light_mask = p_mask; } -RID RendererCanvasCull::canvas_occluder_polygon_create() { +RID RendererCanvasCull::canvas_occluder_polygon_allocate() { + return canvas_light_occluder_polygon_owner.allocate_rid(); +} +void RendererCanvasCull::canvas_occluder_polygon_initialize(RID p_rid) { LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon); occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create(); - return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); + return canvas_light_occluder_polygon_owner.initialize_rid(p_rid, occluder_poly); } void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { @@ -1391,8 +1403,11 @@ void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) { RSG::canvas_render->set_shadow_texture_size(p_size); } -RID RendererCanvasCull::canvas_texture_create() { - return RSG::storage->canvas_texture_create(); +RID RendererCanvasCull::canvas_texture_allocate() { + return RSG::storage->canvas_texture_allocate(); +} +void RendererCanvasCull::canvas_texture_initialize(RID p_rid) { + RSG::storage->canvas_texture_initialize(p_rid); } void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 7496a413ee..b71f8e5a9a 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -101,9 +101,9 @@ public: } }; - RID_PtrOwner<LightOccluderPolygon> canvas_light_occluder_polygon_owner; + RID_PtrOwner<LightOccluderPolygon, true> canvas_light_occluder_polygon_owner; - RID_PtrOwner<RendererCanvasRender::LightOccluderInstance> canvas_light_occluder_owner; + RID_PtrOwner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner; struct Canvas : public RendererViewport::CanvasBase { Set<RID> viewports; @@ -148,9 +148,9 @@ public: } }; - mutable RID_PtrOwner<Canvas> canvas_owner; - RID_PtrOwner<Item> canvas_item_owner; - RID_PtrOwner<RendererCanvasRender::Light> canvas_light_owner; + mutable RID_PtrOwner<Canvas, true> canvas_owner; + RID_PtrOwner<Item, true> canvas_item_owner; + RID_PtrOwner<RendererCanvasRender::Light, true> canvas_light_owner; bool disable_scale; bool sdf_used = false; @@ -168,13 +168,17 @@ public: bool was_sdf_used(); - RID canvas_create(); + RID canvas_allocate(); + void canvas_initialize(RID p_rid); + void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring); void canvas_set_modulate(RID p_canvas, const Color &p_color); void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale); void canvas_set_disable_scale(bool p_disable); - RID canvas_item_create(); + RID canvas_item_allocate(); + void canvas_item_initialize(RID p_rid); + void canvas_item_set_parent(RID p_item, RID p_parent); void canvas_item_set_visible(RID p_item, bool p_visible); @@ -222,7 +226,9 @@ public: void canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false); - RID canvas_light_create(); + RID canvas_light_allocate(); + void canvas_light_initialize(RID p_rid); + void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode); void canvas_light_attach_to_canvas(RID p_light, RID p_canvas); void canvas_light_set_enabled(RID p_light, bool p_enabled); @@ -246,7 +252,9 @@ public: void canvas_light_set_shadow_color(RID p_light, const Color &p_color); void canvas_light_set_shadow_smooth(RID p_light, float p_smooth); - RID canvas_light_occluder_create(); + RID canvas_light_occluder_allocate(); + void canvas_light_occluder_initialize(RID p_rid); + void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas); void canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled); void canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon); @@ -254,14 +262,18 @@ public: void canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform); void canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask); - RID canvas_occluder_polygon_create(); + RID canvas_occluder_polygon_allocate(); + void canvas_occluder_polygon_initialize(RID p_rid); + void canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed); void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode); void canvas_set_shadow_texture_size(int p_size); - RID canvas_texture_create(); + RID canvas_texture_allocate(); + void canvas_texture_initialize(RID p_rid); + void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture); void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess); diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index c35e5e1730..0fdd864d47 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -400,12 +400,14 @@ void ClusterBuilderRD::begin(const Transform &p_view_transform, const CameraMatr void ClusterBuilderRD::bake_cluster() { RENDER_TIMESTAMP(">Bake Cluster"); + RD::get_singleton()->draw_command_begin_label("Bake Light Cluster"); + //clear cluster buffer - RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size); + RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); if (render_element_count > 0) { //clear render buffer - RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size); + RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size, RD::BARRIER_MASK_RASTER); { //fill state uniform @@ -420,12 +422,12 @@ void ClusterBuilderRD::bake_cluster() { state.cluster_depth_offset = (render_element_max / 32); state.cluster_data_size = state.cluster_depth_offset + render_element_max; - RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state); + RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } //update instances - RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements); + RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); RENDER_TIMESTAMP("Render Elements"); @@ -469,7 +471,7 @@ void ClusterBuilderRD::bake_cluster() { RD::get_singleton()->draw_list_draw(draw_list, true, instances); i += instances; } - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE); } //store elements RENDER_TIMESTAMP("Pack Elements"); @@ -491,12 +493,15 @@ void ClusterBuilderRD::bake_cluster() { RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterStore::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1); - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } + } else { + RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } RENDER_TIMESTAMP("<Bake Cluster"); + RD::get_singleton()->draw_command_end_label(); } void ClusterBuilderRD::debug(ElementType p_element) { @@ -519,7 +524,7 @@ void ClusterBuilderRD::debug(ElementType p_element) { RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterDebug::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1); RD::get_singleton()->compute_list_end(); } diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index f1bab19445..a9cadb40df 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -299,15 +299,12 @@ void EffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const copy.push_constant.target[0] = p_rect.position.x; copy.push_constant.target[1] = p_rect.position.y; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -322,15 +319,12 @@ void EffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, copy.push_constant.target[1] = 0; copy.push_constant.camera_z_far = p_lod; - int32_t x_groups = (p_panorama_size.width - 1) / 8 + 1; - int32_t y_groups = (p_panorama_size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -349,15 +343,12 @@ void EffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_ copy.push_constant.camera_z_far = p_z_far; copy.push_constant.camera_z_near = p_z_near; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -374,15 +365,12 @@ void EffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, copy.push_constant.target[0] = p_rect.position.x; copy.push_constant.target[1] = p_rect.position.y; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -400,14 +388,11 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i copy.push_constant.set_color[2] = p_color.b; copy.push_constant.set_color[3] = p_color.a; - int32_t x_groups = (p_region.size.width - 1) / 8 + 1; - int32_t y_groups = (p_region.size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -420,8 +405,6 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back copy.push_constant.section[2] = p_region.size.width; copy.push_constant.section[3] = p_region.size.height; - int32_t x_groups = (p_region.size.width - 1) / 8 + 1; - int32_t y_groups = (p_region.size.height - 1) / 8 + 1; //HORIZONTAL RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]); @@ -431,7 +414,7 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL; RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -442,7 +425,7 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back copy.push_constant.flags = base_flags; RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -452,9 +435,6 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; uint32_t base_flags = 0; - int32_t x_groups = (p_size.width + 7) / 8; - int32_t y_groups = (p_size.height + 7) / 8; - copy.push_constant.section[2] = p_size.x; copy.push_constant.section[3] = p_size.y; @@ -479,16 +459,13 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; - int32_t y_groups = (p_screen_size.height - 1) / 8 + 1; - { //scale color and depth to half ssr_scale.push_constant.camera_z_far = p_camera.get_z_far(); ssr_scale.push_constant.camera_z_near = p_camera.get_z_near(); @@ -506,7 +483,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); } @@ -547,7 +524,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R } RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); } if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { @@ -585,7 +562,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -600,7 +577,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); } RD::get_singleton()->compute_list_end(); @@ -609,9 +586,6 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; - int32_t y_groups = (p_screen_size.height - 1) / 8 + 1; - Plane p = p_camera.xform4(Plane(1, 0, -1, 1)); p.normal /= p.d; float unit_size = p.normal.x; @@ -635,7 +609,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -646,7 +620,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept sss.push_constant.vertical = true; RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -690,15 +664,12 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S copy.push_constant.section[2] = p_size.width; copy.push_constant.section[3] = p_size.height; - int32_t x_groups = (p_size.width - 1) / 8 + 1; - int32_t y_groups = (p_size.height - 1) / 8 + 1; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); RD::get_singleton()->compute_list_end(); } @@ -719,7 +690,7 @@ void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffe RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER); } void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { @@ -804,10 +775,7 @@ void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_ RD::get_singleton()->compute_list_set_push_constant(compute_list, &luminance_reduce.push_constant, sizeof(LuminanceReducePushConstant)); - int32_t x_groups = (luminance_reduce.push_constant.source_size[0] - 1) / 8 + 1; - int32_t y_groups = (luminance_reduce.push_constant.source_size[1] - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, luminance_reduce.push_constant.source_size[0], luminance_reduce.push_constant.source_size[1], 1); luminance_reduce.push_constant.source_size[0] = MAX(luminance_reduce.push_constant.source_size[0] / 8, 1); luminance_reduce.push_constant.source_size[1] = MAX(luminance_reduce.push_constant.source_size[1] / 8, 1); @@ -848,14 +816,12 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_texture), 1); - int32_t x_groups = (p_base_texture_size.x - 1) / 8 + 1; - int32_t y_groups = (p_base_texture_size.y - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x; bokeh.push_constant.size[1] = p_base_texture_size.y; RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { @@ -872,8 +838,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); - x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; - y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; bokeh.push_constant.half_size = true; @@ -887,7 +851,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //third pass @@ -903,7 +867,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); RD::get_singleton()->compute_list_add_barrier(compute_list); if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { @@ -914,8 +878,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture2), 1); - x_groups = (p_base_texture_size.x - 1) / 8 + 1; - y_groups = (p_base_texture_size.y - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x; bokeh.push_constant.size[1] = p_base_texture_size.y; bokeh.push_constant.half_size = false; @@ -923,7 +885,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1); } } else { //circle @@ -941,15 +903,13 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1); - x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1; - y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x >> 1; bokeh.push_constant.size[1] = p_base_texture_size.y >> 1; bokeh.push_constant.half_size = true; RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //circle is just one pass, then upscale @@ -961,8 +921,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1); - x_groups = (p_base_texture_size.x - 1) / 8 + 1; - y_groups = (p_base_texture_size.y - 1) / 8 + 1; bokeh.push_constant.size[0] = p_base_texture_size.x; bokeh.push_constant.size[1] = p_base_texture_size.y; bokeh.push_constant.half_size = false; @@ -970,7 +928,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1); } RD::get_singleton()->compute_list_end(); @@ -995,10 +953,9 @@ void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 2); RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant)); - int x_groups = ((p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = ((p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; + Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)); - RD::get_singleton()->compute_list_dispatch(p_compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1); } RD::get_singleton()->compute_list_add_barrier(p_compute_list); } @@ -1072,10 +1029,9 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep } RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant)); - int x_groups = (MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = (MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; + Size2i size(MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)), MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1))); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); RD::get_singleton()->draw_command_end_label(); // Downsample SSAO } @@ -1193,21 +1149,19 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]); gather_ssao(compute_list, p_ao_pong_slices, p_settings, true); //generate importance map - int x_groups = (p_settings.quarter_screen_size.x - 1) / 8 + 1; - int y_groups = (p_settings.quarter_screen_size.y - 1) / 8 + 1; RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //process importance map A RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map_pong), 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); //process Importance Map B RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]); @@ -1215,7 +1169,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.counter_uniform_set, 2); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_ADAPTIVE]); @@ -1272,10 +1226,8 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep } RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant)); - int x_groups = ((p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - int y_groups = ((p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + Size2i size(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1); } if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) { @@ -1313,18 +1265,15 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant)); - int x_groups = (p_settings.full_screen_size.x - 1) / 8 + 1; - int y_groups = (p_settings.full_screen_size.y - 1) / 8 + 1; - - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); RD::get_singleton()->draw_command_end_label(); // Interleave } RD::get_singleton()->draw_command_end_label(); //SSAO - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); //wait for upcoming transfer int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero); + RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier } void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) { @@ -1337,12 +1286,9 @@ void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_normal), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_roughness), 1); - int x_groups = (p_size.x - 1) / 8 + 1; - int y_groups = (p_size.y - 1) / 8 + 1; - RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness_limiter.push_constant, sizeof(RoughnessLimiterPushConstant)); //not used but set anyway - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.x, p_size.y, 1); RD::get_singleton()->compute_list_end(); } @@ -1455,7 +1401,7 @@ void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_ RD::get_singleton()->draw_list_draw(draw_list, true); } -void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) { +void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { ResolvePushConstant push_constant; push_constant.screen_size[0] = p_screen_size.x; push_constant.screen_size[1] = p_screen_size.y; @@ -1472,54 +1418,9 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) { - uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 }; - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_source_shadow, p_dest_shadow), 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); -} -void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) { - uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 }; - - switch (p_filter) { - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED: - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW: { - push_constant[5] = 0; - } break; - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM: { - push_constant[5] = 9; - } break; - case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH: { - push_constant[5] = 18; - } break; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_FILTER]); - if (p_vertical) { - push_constant[6] = 1; - push_constant[7] = 0; - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_shadow, p_backing_shadow), 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); - } - if (p_vertical && p_horizontal) { - RD::get_singleton()->compute_list_add_barrier(compute_list); - } - if (p_horizontal) { - push_constant[6] = 0; - push_constant[7] = 1; - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_backing_shadow, p_shadow), 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1); - } + RD::get_singleton()->compute_list_end(p_barrier); } void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { @@ -2018,20 +1919,6 @@ EffectsRD::EffectsRD() { } { - Vector<String> shadow_reduce_modes; - shadow_reduce_modes.push_back("\n#define MODE_REDUCE\n"); - shadow_reduce_modes.push_back("\n#define MODE_FILTER\n"); - - shadow_reduce.shader.initialize(shadow_reduce_modes); - - shadow_reduce.shader_version = shadow_reduce.shader.version_create(); - - for (int i = 0; i < SHADOW_REDUCE_MAX; i++) { - shadow_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(shadow_reduce.shader.version_get_shader(shadow_reduce.shader_version, i)); - } - } - - { Vector<String> sort_modes; sort_modes.push_back("\n#define MODE_SORT_BLOCK\n"); sort_modes.push_back("\n#define MODE_SORT_STEP\n"); @@ -2119,5 +2006,4 @@ EffectsRD::~EffectsRD() { ssr_scale.shader.version_free(ssr_scale.shader_version); sss.shader.version_free(sss.shader_version); tonemap.shader.version_free(tonemap.shader_version); - shadow_reduce.shader.version_free(shadow_reduce.shader_version); } diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 00309b4d0f..1ba25e301b 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -46,7 +46,6 @@ #include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h" @@ -597,18 +596,6 @@ class EffectsRD { RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels } resolve; - enum ShadowReduceMode { - SHADOW_REDUCE_REDUCE, - SHADOW_REDUCE_FILTER, - SHADOW_REDUCE_MAX - }; - - struct ShadowReduce { - ShadowReduceShaderRD shader; - RID shader_version; - RID pipelines[SHADOW_REDUCE_MAX]; - } shadow_reduce; - enum SortMode { SORT_MODE_BLOCK, SORT_MODE_STEP, @@ -763,10 +750,7 @@ public: void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection); void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); - void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples); - - void reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RenderingDevice::ComputeListID compute_list); - void filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RS::EnvVolumetricFogShadowFilter p_filter, RenderingDevice::ComputeListID compute_list, bool p_vertical = true, bool p_horizontal = true); + void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void sort_buffer(RID p_uniform_set, int p_size); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index c354ad8c1c..2bf3c436a8 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1622,7 +1622,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp); } - Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); + Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; @@ -2695,7 +2695,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET); } - default_canvas_texture = storage->canvas_texture_create(); + default_canvas_texture = storage->canvas_texture_allocate(); + storage->canvas_texture_initialize(default_canvas_texture); state.shadow_texture_size = GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"); @@ -2706,9 +2707,14 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { state.time = 0; { - default_canvas_group_shader = storage->shader_create(); + default_canvas_group_shader = storage->shader_allocate(); + storage->shader_initialize(default_canvas_group_shader); + storage->shader_set_code(default_canvas_group_shader, "shader_type canvas_item; \nvoid fragment() {\n\tvec4 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0); if (c.a > 0.0001) c.rgb/=c.a; COLOR *= c; \n}\n"); - default_canvas_group_material = storage->material_create(); + + default_canvas_group_material = storage->material_allocate(); + storage->material_initialize(default_canvas_group_material); + storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp index a20a5073c3..15ecc11144 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp @@ -453,7 +453,7 @@ void RendererSceneRenderForward::MaterialData::update_parameters(const Map<Strin //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); - RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); + RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER); } uint32_t tex_uniform_count = shader_data->texture_uniforms.size(); @@ -810,10 +810,20 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); - float old_offset[2] = { 0, 0 }; + SceneState::PushConstant push_constant; + + if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { + push_constant.uv_offset = Math::make_half_float(p_params->uv_offset.y) << 16; + push_constant.uv_offset |= Math::make_half_float(p_params->uv_offset.x); + } else { + push_constant.uv_offset = 0; + } for (uint32_t i = p_from_element; i < p_to_element; i++) { const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i]; + const RenderElementInfo &element_info = p_params->element_info[i]; + + push_constant.base_index = i + p_params->element_offset; RID material_uniform_set; ShaderData *shader; @@ -834,13 +844,6 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList continue; } - if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { - old_offset[0] = surf->owner->push_constant.lightmap_uv_scale[0]; - old_offset[1] = surf->owner->push_constant.lightmap_uv_scale[1]; - surf->owner->push_constant.lightmap_uv_scale[0] = p_params->uv_offset.x; - surf->owner->push_constant.lightmap_uv_scale[1] = p_params->uv_offset.y; - } - //find cull variant ShaderData::CullVariant cull_variant; @@ -862,16 +865,16 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList switch (p_params->pass_mode) { case PASS_MODE_COLOR: case PASS_MODE_COLOR_TRANSPARENT: { - if (surf->sort.uses_lightmap) { + if (element_info.uses_lightmap) { shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS; - } else if (surf->sort.uses_forward_gi) { + } else if (element_info.uses_forward_gi) { shader_version = SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI; } else { shader_version = SHADER_VERSION_COLOR_PASS; } } break; case PASS_MODE_COLOR_SPECULAR: { - if (surf->sort.uses_lightmap) { + if (element_info.uses_lightmap) { shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR; } else { shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR; @@ -913,31 +916,7 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format); } - if (p_params->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(mesh_surface)) { - //lod - Vector3 support_min = surf->owner->transformed_aabb.get_support(-p_params->lod_plane.normal); - Vector3 support_max = surf->owner->transformed_aabb.get_support(p_params->lod_plane.normal); - - float distance_min = p_params->lod_plane.distance_to(support_min); - float distance_max = p_params->lod_plane.distance_to(support_max); - - float distance = 0.0; - - if (distance_min * distance_max < 0.0) { - //crossing plane - distance = 0.0; - } else if (distance_min >= 0.0) { - distance = distance_min; - } else if (distance_max <= 0.0) { - distance = -distance_max; - } - - index_array_rd = storage->mesh_surface_get_index_array_with_lod(mesh_surface, surf->owner->lod_model_scale * surf->owner->lod_bias, distance * p_params->lod_distance_multiplier, p_params->screen_lod_threshold); - - } else { - //no lod - index_array_rd = storage->mesh_surface_get_index_array(mesh_surface); - } + index_array_rd = storage->mesh_surface_get_index_array(mesh_surface, element_info.lod_index); if (prev_vertex_array_rd != vertex_array_rd) { RD::get_singleton()->draw_list_bind_vertex_array(draw_list, vertex_array_rd); @@ -974,14 +953,11 @@ void RendererSceneRenderForward::_render_list_template(RenderingDevice::DrawList prev_material_uniform_set = material_uniform_set; } - RD::get_singleton()->draw_list_set_push_constant(draw_list, &surf->owner->push_constant, sizeof(GeometryInstanceForward::PushConstant)); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), surf->owner->instance_count); - - if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) { - surf->owner->push_constant.lightmap_uv_scale[0] = old_offset[0]; - surf->owner->push_constant.lightmap_uv_scale[1] = old_offset[1]; - } + uint32_t instance_count = surf->owner->instance_count > 1 ? surf->owner->instance_count : element_info.repeat; + RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); + i += element_info.repeat - 1; //skip equal elements } } @@ -1039,16 +1015,16 @@ void RendererSceneRenderForward::_render_list_with_threads(RenderListParameters thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures); RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RendererSceneRenderForward::_render_list_thread_function, p_params); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->draw_list_end(p_params->barrier); } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures); _render_list(draw_list, fb_format, p_params, 0, p_params->element_count); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->draw_list_end(p_params->barrier); } } -void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { +void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; @@ -1287,22 +1263,120 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount(); scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit(); - RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo); + if (p_index >= (int)scene_state.uniform_buffers.size()) { + uint32_t from = scene_state.uniform_buffers.size(); + scene_state.uniform_buffers.resize(p_index + 1); + render_pass_uniform_sets.resize(p_index + 1); + for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { + scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); + } + } + RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER); +} + +void RendererSceneRenderForward::_update_instance_data_buffer(RenderListType p_render_list) { + if (scene_state.instance_data[p_render_list].size() > 0) { + if (scene_state.instance_buffer[p_render_list] == RID() || scene_state.instance_buffer_size[p_render_list] < scene_state.instance_data[p_render_list].size()) { + if (scene_state.instance_buffer[p_render_list] != RID()) { + RD::get_singleton()->free(scene_state.instance_buffer[p_render_list]); + } + uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), scene_state.instance_data[p_render_list].size())); + scene_state.instance_buffer[p_render_list] = RD::get_singleton()->storage_buffer_create(new_size * sizeof(SceneState::InstanceData)); + scene_state.instance_buffer_size[p_render_list] = new_size; + } + RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER); + } +} +void RendererSceneRenderForward::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) { + RenderList *rl = &render_list[p_render_list]; + uint32_t element_total = p_max_elements >= 0 ? uint32_t(p_max_elements) : rl->elements.size(); + + scene_state.instance_data[p_render_list].resize(p_offset + element_total); + rl->element_info.resize(p_offset + element_total); + + uint32_t repeats = 0; + GeometryInstanceSurfaceDataCache *prev_surface = nullptr; + for (uint32_t i = 0; i < element_total; i++) { + GeometryInstanceSurfaceDataCache *surface = rl->elements[i + p_offset]; + GeometryInstanceForward *inst = surface->owner; + + SceneState::InstanceData &instance_data = scene_state.instance_data[p_render_list][i + p_offset]; + + if (inst->store_transform_cache) { + RendererStorageRD::store_transform(inst->transform, instance_data.transform); + } else { + RendererStorageRD::store_transform(Transform(), instance_data.transform); + } + + instance_data.flags = inst->flags_cache; + instance_data.gi_offset = inst->gi_offset_cache; + instance_data.layer_mask = inst->layer_mask; + instance_data.instance_uniforms_ofs = uint32_t(inst->shader_parameters_offset); + instance_data.lightmap_uv_scale[0] = inst->lightmap_uv_scale.position.x; + instance_data.lightmap_uv_scale[1] = inst->lightmap_uv_scale.position.y; + instance_data.lightmap_uv_scale[2] = inst->lightmap_uv_scale.size.x; + instance_data.lightmap_uv_scale[3] = inst->lightmap_uv_scale.size.y; + + bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); + + if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2) { + //this element is the same as the previous one, count repeats to draw it using instancing + repeats++; + } else { + if (repeats > 0) { + for (uint32_t j = 1; j <= repeats; j++) { + rl->element_info[p_offset + i - j].repeat = j; + } + } + repeats = 1; + } + + RenderElementInfo &element_info = rl->element_info[p_offset + i]; + + element_info.lod_index = surface->sort.lod_index; + element_info.uses_forward_gi = surface->sort.uses_forward_gi; + element_info.uses_lightmap = surface->sort.uses_lightmap; + + if (cant_repeat) { + prev_surface = nullptr; + } else { + prev_surface = surface; + } + } + + if (repeats > 0) { + for (uint32_t j = 1; j <= repeats; j++) { + rl->element_info[p_offset + element_total - j].repeat = j; + } + } + + if (p_update_buffer) { + _update_instance_data_buffer(p_render_list); + } } -void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi) { - scene_state.used_sss = false; - scene_state.used_screen_texture = false; - scene_state.used_normal_texture = false; - scene_state.used_depth_texture = false; +void RendererSceneRenderForward::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) { + if (p_render_list == RENDER_LIST_OPAQUE) { + scene_state.used_sss = false; + scene_state.used_screen_texture = false; + scene_state.used_normal_texture = false; + scene_state.used_depth_texture = false; + } + uint32_t lightmap_captures_used = 0; Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); near_plane.d += p_cam_projection.get_z_near(); float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near(); - uint32_t lightmap_captures_used = 0; + RenderList *rl = &render_list[p_render_list]; _update_dirty_geometry_instances(); - render_list.clear(); + + if (!p_append) { + rl->clear(); + if (p_render_list == RENDER_LIST_OPAQUE) { + render_list[RENDER_LIST_ALPHA].clear(); //opaque fills alpha too + } + } //fill list @@ -1318,7 +1392,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst bool uses_lightmap = false; bool uses_gi = false; - if (p_pass_mode == PASS_MODE_COLOR) { + if (p_render_list == RENDER_LIST_OPAQUE) { //setup GI if (inst->lightmap_instance.is_valid()) { @@ -1330,15 +1404,15 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst } } if (lightmap_cull_index >= 0) { - inst->push_constant.gi_offset &= 0xFFFF; - inst->push_constant.gi_offset |= lightmap_cull_index; + inst->gi_offset_cache = inst->lightmap_slice_index << 16; + inst->gi_offset_cache |= lightmap_cull_index; flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP; if (scene_state.lightmap_has_sh[lightmap_cull_index]) { flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP; } uses_lightmap = true; } else { - inst->push_constant.gi_offset = 0xFFFFFFFF; + inst->gi_offset_cache = 0xFFFFFFFF; } } else if (inst->lightmap_sh) { @@ -1352,7 +1426,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst lcd.sh[j * 4 + 3] = src_capture[j].a; } flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE; - inst->push_constant.gi_offset = lightmap_captures_used; + inst->gi_offset_cache = lightmap_captures_used; lightmap_captures_used++; uses_lightmap = true; } @@ -1379,7 +1453,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst SWAP(probe0_index, probe1_index); } - inst->push_constant.gi_offset = probe0_index | (probe1_index << 16); + inst->gi_offset_cache = probe0_index | (probe1_index << 16); flags |= INSTANCE_DATA_FLAG_USE_GIPROBE; uses_gi = true; } else { @@ -1387,11 +1461,11 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst flags |= INSTANCE_DATA_FLAG_USE_SDFGI; uses_gi = true; } - inst->push_constant.gi_offset = 0xFFFFFFFF; + inst->gi_offset_cache = 0xFFFFFFFF; } } } - inst->push_constant.flags = flags; + inst->flags_cache = flags; GeometryInstanceSurfaceDataCache *surf = inst->surface_caches; @@ -1399,12 +1473,39 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst surf->sort.uses_forward_gi = 0; surf->sort.uses_lightmap = 0; + // LOD + + if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) { + //lod + Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal); + Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal); + + float distance_min = p_lod_plane.distance_to(lod_support_min); + float distance_max = p_lod_plane.distance_to(lod_support_max); + + float distance = 0.0; + + if (distance_min * distance_max < 0.0) { + //crossing plane + distance = 0.0; + } else if (distance_min >= 0.0) { + distance = distance_min; + } else if (distance_max <= 0.0) { + distance = -distance_max; + } + + surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold); + } else { + surf->sort.lod_index = 0; + } + + // ADD Element if (p_pass_mode == PASS_MODE_COLOR) { if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) { - render_list.add_element(surf); + rl->add_element(surf); } if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) { - render_list.add_alpha_element(surf); + render_list[RENDER_LIST_ALPHA].add_element(surf); if (uses_gi) { surf->sort.uses_forward_gi = 1; } @@ -1429,11 +1530,11 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) { if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) { - render_list.add_element(surf); + rl->add_element(surf); } } else { if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) { - render_list.add_element(surf); + rl->add_element(surf); } } @@ -1443,8 +1544,8 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst } } - if (lightmap_captures_used) { - RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures); + if (p_render_list == RENDER_LIST_OPAQUE && lightmap_captures_used) { + RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, RD::BARRIER_MASK_RASTER); } } @@ -1473,29 +1574,21 @@ void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<RID> &p_light scene_state.lightmaps_used++; } if (scene_state.lightmaps_used > 0) { - RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps); + RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, RD::BARRIER_MASK_RASTER); } } -void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) { +void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) { RenderBufferDataForward *render_buffer = nullptr; if (p_render_buffer.is_valid()) { render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer); } //first of all, make a new render pass - render_pass++; - //fill up ubo RENDER_TIMESTAMP("Setup 3D Scene"); - if (p_reflection_probe.is_valid()) { - scene_state.ubo.reflection_multiplier = 0.0; - } else { - scene_state.ubo.reflection_multiplier = 1.0; - } - float lod_distance_multiplier = p_cam_projection.get_lod_multiplier(); Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); @@ -1508,7 +1601,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); scene_state.ubo.viewport_size[0] = vp_he.x; scene_state.ubo.viewport_size[1] = vp_he.y; - scene_state.ubo.directional_light_count = p_directional_light_count; + scene_state.ubo.directional_light_count = 0; Size2i screen_size; RID opaque_framebuffer; @@ -1592,13 +1685,21 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf ERR_FAIL(); //bug? } + RD::get_singleton()->draw_command_begin_label("Render Setup"); + _setup_lightmaps(p_lightmaps, p_cam_transform); _setup_giprobes(p_gi_probes); _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe); + _fill_render_list(RENDER_LIST_OPAQUE, p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + render_list[RENDER_LIST_OPAQUE].sort_by_key(); + render_list[RENDER_LIST_ALPHA].sort_by_depth(); + _fill_instance_data(RENDER_LIST_OPAQUE); + _fill_instance_data(RENDER_LIST_ALPHA); + + RD::get_singleton()->draw_command_end_label(); bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED; @@ -1682,8 +1783,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf clear_color = p_default_bg_color; } - render_list.sort_by_key(false); - bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION; bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES; bool depth_pre_pass = !low_end && depth_framebuffer.is_valid(); @@ -1691,42 +1790,64 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment); bool continue_depth = false; if (depth_pre_pass) { //depth pre pass - RENDER_TIMESTAMP("Render Depth Pre-Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + bool needs_pre_resolve = _needs_post_prepass_render(using_sdfgi || using_giprobe); + if (needs_pre_resolve) { + RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)"); + } else { + RENDER_TIMESTAMP("Render Depth Pre-Pass"); + } + if (needs_pre_resolve) { + //pre clear the depth framebuffer, as AMD (and maybe others?) use compute for it, and barrier other compute shaders. + RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear); + RD::get_singleton()->draw_list_end(); + //start compute processes here, so they run at the same time as depth pre-pass + _post_prepass_render(using_sdfgi || using_giprobe); + } - bool finish_depth = using_ssao || using_sdfgi || using_giprobe; - RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass"); - _render_list_with_threads(&render_list_params, depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear); + + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + + bool finish_depth = using_ssao || using_sdfgi || using_giprobe; + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); + RD::get_singleton()->draw_command_end_label(); + + if (needs_pre_resolve) { + _pre_resolve_render(using_sdfgi || using_giprobe); + } + if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { RENDER_TIMESTAMP("Resolve Depth Pre-Pass"); - RD::get_singleton()->draw_command_insert_label("Resolve Depth Pre-Pass"); + RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass"); if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) { + if (needs_pre_resolve) { + RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); + } static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 }; storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_giprobe ? render_buffer->giprobe_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_giprobe ? render_buffer->giprobe_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]); } else if (finish_depth) { RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); } + RD::get_singleton()->draw_command_end_label(); } continue_depth = !finish_depth; } - if (using_ssao) { - _process_ssao(p_render_buffer, p_environment, render_buffer->normal_roughness_buffer, p_cam_projection); - } + _pre_opaque_render(using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID()); - if (using_sdfgi || using_giprobe) { - _process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes); - } + RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); + + scene_state.ubo.directional_light_count = _get_render_state_directional_light_count(); _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid()); RENDER_TIMESTAMP("Render Opaque Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss; bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; @@ -1747,10 +1868,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf } RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; - RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); - RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); - _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - RD::get_singleton()->draw_command_end_label(); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE); @@ -1758,6 +1877,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf } } + RD::get_singleton()->draw_command_end_label(); + if (debug_giprobes) { //debug giprobes bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); @@ -1837,32 +1958,44 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf RENDER_TIMESTAMP("Render Transparent Pass"); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); - render_list.sort_by_reverse_depth_and_priority(true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); + + _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); { - RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); - RenderListParameters render_list_params(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); - RD::get_singleton()->draw_command_end_label(); } + RD::get_singleton()->draw_command_end_label(); + + RD::get_singleton()->draw_command_begin_label("Resolve"); + if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color); } -} -void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { - RENDER_TIMESTAMP("Setup Rendering Shadow"); + RD::get_singleton()->draw_command_end_label(); +} +void RendererSceneRenderForward::_render_shadow_begin() { + scene_state.shadow_passes.clear(); + RD::get_singleton()->draw_command_begin_label("Shadow Setup"); _update_render_base_uniform_set(); - render_pass++; + render_list[RENDER_LIST_SECONDARY].clear(); + scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); +} +void RendererSceneRenderForward::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { + uint32_t shadow_pass_index = scene_state.shadow_passes.size(); + + SceneState::ShadowPass shadow_pass; scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake); + _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { p_screen_lod_threshold = 0.0; @@ -1870,13 +2003,11 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; - _fill_render_list(p_instances, pass_mode, p_projection, p_transform); - - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); - - RENDER_TIMESTAMP("Render Shadow"); - - render_list.sort_by_key(false); + uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, false, false, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true); + uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; + render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); + _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false); { //regular forward for now @@ -1884,49 +2015,87 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr if (p_flip_y) { flip_cull = !flip_cull; } - RD::get_singleton()->draw_command_begin_label("Render Shadow"); - RenderListParameters render_list_params(render_list.elements, render_list.element_count, flip_cull, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); - _render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : RD::INITIAL_ACTION_CONTINUE, p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, Vector<Color>(), 1.0, 0, p_rect); - RD::get_singleton()->draw_command_end_label(); + + shadow_pass.element_from = render_list_from; + shadow_pass.element_count = render_list_size; + shadow_pass.flip_cull = flip_cull; + shadow_pass.pass_mode = pass_mode; + + shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete + shadow_pass.camera_plane = p_camera_plane; + shadow_pass.screen_lod_threshold = p_screen_lod_threshold; + shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier; + + shadow_pass.framebuffer = p_framebuffer; + shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE); + shadow_pass.final_depth_action = p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE; + shadow_pass.rect = p_rect; + + scene_state.shadow_passes.push_back(shadow_pass); } } +void RendererSceneRenderForward::_render_shadow_process() { + _update_instance_data_buffer(RENDER_LIST_SECONDARY); + //render shadows one after the other, so this can be done un-barriered and the driver can optimize (as well as allow us to run compute at the same time) + + for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { + //render passes need to be configured after instance buffer is done, since they need the latest version + SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>(), false, i); + } + + RD::get_singleton()->draw_command_end_label(); +} +void RendererSceneRenderForward::_render_shadow_end(uint32_t p_barrier) { + RD::get_singleton()->draw_command_begin_label("Shadow Render"); + + for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { + SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); + _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); + } + + if (p_barrier != RD::BARRIER_MASK_NO_BARRIER) { + RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, p_barrier); + } + RD::get_singleton()->draw_command_end_label(); +} + void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup Render Collider Heightfield"); - _update_render_base_uniform_set(); - - render_pass++; + RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false); PassMode pass_mode = PASS_MODE_SHADOW; - _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); RENDER_TIMESTAMP("Render Collider Heightfield"); - render_list.sort_by_key(false); - { //regular forward for now - RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); - RenderListParameters render_list_params(render_list.elements, render_list.element_count, false, pass_mode, true, rp_uniform_set); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, true, rp_uniform_set); _render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); - RD::get_singleton()->draw_command_end_label(); } + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering Material"); - _update_render_base_uniform_set(); + RD::get_singleton()->draw_command_begin_label("Render Material"); - render_pass++; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = false; @@ -1934,16 +2103,16 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); RENDER_TIMESTAMP("Render Material"); - render_list.sort_by_key(false); - { - RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -1955,14 +2124,16 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); RD::get_singleton()->draw_list_end(); } + + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); - _update_render_base_uniform_set(); + RD::get_singleton()->draw_command_begin_label("Render UV2"); - render_pass++; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = true; @@ -1970,16 +2141,16 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance * _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform()); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); RENDER_TIMESTAMP("Render Material"); - render_list.sort_by_key(false); - { - RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, true); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, true); //regular forward for now Vector<Color> clear; clear.push_back(Color(0, 0, 0, 0)); @@ -2015,23 +2186,24 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance * RD::get_singleton()->draw_list_end(); } + + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { RENDER_TIMESTAMP("Render SDFGI"); + RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); + _update_render_base_uniform_set(); RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers); ERR_FAIL_COND(!render_buffer); - render_pass++; - PassMode pass_mode = PASS_MODE_SDF; - _fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform()); - render_list.sort_by_key(false); - - RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); + _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + _fill_instance_data(RENDER_LIST_SECONDARY); Vector3 half_extents = p_bounds.size * 0.5; Vector3 center = p_bounds.position + half_extents; @@ -2084,15 +2256,19 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); + RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); + Map<Size2i, RID>::Element *E = sdfgi_framebuffer_size_cache.find(fb_size); if (!E) { RID fb = RD::get_singleton()->framebuffer_create_empty(fb_size); E = sdfgi_framebuffer_size_cache.insert(fb_size, fb); } - RenderListParameters render_list_params(render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, false); _render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs); } + + RD::get_singleton()->draw_command_end_label(); } void RendererSceneRenderForward::_base_uniforms_changed() { @@ -2144,21 +2320,13 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 3; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffer); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_omni_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 5; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_spot_light_buffer()); uniforms.push_back(u); @@ -2166,35 +2334,35 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 6; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 7; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 8; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 9; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 10; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); @@ -2202,7 +2370,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 11; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); u.ids.push_back(decal_atlas); @@ -2210,7 +2378,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 12; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_decal_buffer()); uniforms.push_back(u); @@ -2219,7 +2387,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 13; + u.binding = 12; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2227,7 +2395,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { if (!low_end) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 14; + u.binding = 13; u.ids.push_back(sdfgi_get_ubo()); uniforms.push_back(u); } @@ -2236,10 +2404,9 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } } -RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas) { - if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) { - RD::get_singleton()->free(render_pass_uniform_set); - } +RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) { + //there should always be enough uniform buffers for render passes, otherwise bugs + ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID()); RenderBufferDataForward *rb = nullptr; if (p_render_buffers.is_valid()) { @@ -2251,6 +2418,24 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff Vector<RD::Uniform> uniforms; { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.ids.push_back(scene_state.uniform_buffers[p_index]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + RID instance_buffer = scene_state.instance_buffer[p_render_list]; + if (instance_buffer == RID()) { + instance_buffer = default_vec4_xform_buffer; // any buffer will do since its not used + } + u.ids.push_back(instance_buffer); + uniforms.push_back(u); + } + { RID radiance_texture; if (p_radiance_texture.is_valid()) { radiance_texture = p_radiance_texture; @@ -2258,7 +2443,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; - u.binding = 0; + u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(radiance_texture); uniforms.push_back(u); @@ -2267,7 +2452,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); RD::Uniform u; - u.binding = 1; + u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { u.ids.push_back(ref_texture); @@ -2279,7 +2464,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 2; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; if (p_shadow_atlas.is_valid()) { @@ -2293,7 +2478,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 3; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { u.ids.push_back(directional_shadow_get_texture()); @@ -2304,7 +2489,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 4; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); @@ -2323,7 +2508,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 5; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2344,7 +2529,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 6; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer; u.ids.push_back(cb); @@ -2353,7 +2538,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 7; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); @@ -2361,7 +2546,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 8; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2372,7 +2557,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff if (!low_end) { { RD::Uniform u; - u.binding = 9; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL); u.ids.push_back(texture); @@ -2381,7 +2566,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 10; + u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID(); RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2391,7 +2576,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 11; + u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID(); RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2401,7 +2586,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 12; + u.binding = 14; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID(); RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2410,7 +2595,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 13; + u.binding = 15; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID t; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { @@ -2423,7 +2608,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 14; + u.binding = 16; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers)); @@ -2434,14 +2619,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 15; + u.binding = 17; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 16; + u.binding = 18; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = RID(); if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) { @@ -2457,8 +2642,16 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } } - render_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET); - return render_pass_uniform_set; + if (p_index >= (int)render_pass_uniform_sets.size()) { + render_pass_uniform_sets.resize(p_index + 1); + } + + if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) { + RD::get_singleton()->free(render_pass_uniform_sets[p_index]); + } + + render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET); + return render_pass_uniform_sets[p_index]; } RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) { @@ -2469,10 +2662,24 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed Vector<RD::Uniform> uniforms; { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.ids.push_back(scene_state.uniform_buffers[0]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 1; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); + uniforms.push_back(u); + } + { // No radiance texture. RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RD::Uniform u; - u.binding = 0; + u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(radiance_texture); uniforms.push_back(u); @@ -2482,7 +2689,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed // No reflection atlas. RID ref_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); RD::Uniform u; - u.binding = 1; + u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(ref_texture); uniforms.push_back(u); @@ -2491,7 +2698,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No shadow atlas. RD::Uniform u; - u.binding = 2; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); @@ -2501,7 +2708,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No directional shadow atlas. RD::Uniform u; - u.binding = 3; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); @@ -2511,7 +2718,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No Lightmaps RD::Uniform u; - u.binding = 4; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); @@ -2525,7 +2732,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No GIProbes RD::Uniform u; - u.binding = 5; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2538,7 +2745,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { RD::Uniform u; - u.binding = 6; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = default_vec4_xform_buffer; u.ids.push_back(cb); @@ -2550,28 +2757,28 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 7; + u.binding = 9; u.ids.push_back(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 8; + u.binding = 10; u.ids.push_back(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; + u.binding = 11; u.ids.push_back(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 10; + u.binding = 12; u.ids.push_back(p_geom_facing_texture); uniforms.push_back(u); } @@ -2709,10 +2916,11 @@ void RendererSceneRenderForward::_geometry_instance_add_surface_with_material(Ge sdcache->sort.sort_key1 = 0; sdcache->sort.sort_key2 = 0; - sdcache->sort.surface_type = ginstance->data->base_type; - sdcache->sort.material_id = p_material_id; + sdcache->sort.surface_index = p_surface; + sdcache->sort.material_id_low = p_material_id & 0x3FFF; + sdcache->sort.material_id_hi = p_material_id >> 14; sdcache->sort.shader_id = p_shader_id; - sdcache->sort.geometry_id = p_mesh.get_local_index(); + sdcache->sort.geometry_id = p_mesh.get_local_index(); //only meshes can repeat anyway sdcache->sort.uses_forward_gi = ginstance->can_sdfgi; sdcache->sort.priority = p_material->priority; } @@ -2842,11 +3050,6 @@ void RendererSceneRenderForward::_geometry_instance_update(GeometryInstance *p_g //Fill push constant - ginstance->push_constant.instance_uniforms_ofs = ginstance->data->shader_parameters_offset >= 0 ? ginstance->data->shader_parameters_offset : 0; - ginstance->push_constant.layer_mask = ginstance->data->layer_mask; - ginstance->push_constant.flags = 0; - ginstance->push_constant.gi_offset = 0xFFFFFFFF; //disabled - bool store_transform = true; if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) { @@ -2903,21 +3106,10 @@ void RendererSceneRenderForward::_geometry_instance_update(GeometryInstance *p_g } } - if (store_transform) { - RendererStorageRD::store_transform(ginstance->data->transform, ginstance->push_constant.transform); - } else { - RendererStorageRD::store_transform(Transform(), ginstance->push_constant.transform); - } - + ginstance->store_transform_cache = store_transform; ginstance->can_sdfgi = false; - if (lightmap_instance_is_valid(ginstance->lightmap_instance)) { - ginstance->push_constant.gi_offset = ginstance->data->lightmap_slice_index << 16; - ginstance->push_constant.lightmap_uv_scale[0] = ginstance->data->lightmap_uv_scale.position.x; - ginstance->push_constant.lightmap_uv_scale[1] = ginstance->data->lightmap_uv_scale.position.y; - ginstance->push_constant.lightmap_uv_scale[2] = ginstance->data->lightmap_uv_scale.size.width; - ginstance->push_constant.lightmap_uv_scale[3] = ginstance->data->lightmap_uv_scale.size.height; - } else if (!low_end) { + if (!lightmap_instance_is_valid(ginstance->lightmap_instance) && !low_end) { if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) { ginstance->can_sdfgi = true; } @@ -3007,8 +3199,7 @@ void RendererSceneRenderForward::geometry_instance_set_mesh_instance(GeometryIns void RendererSceneRenderForward::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - RendererStorageRD::store_transform(p_transform, ginstance->push_constant.transform); - ginstance->data->transform = p_transform; + ginstance->transform = p_transform; ginstance->mirror = p_transform.basis.determinant() < 0; ginstance->data->aabb = p_aabb; ginstance->transformed_aabb = p_transformed_aabb; @@ -3043,8 +3234,8 @@ void RendererSceneRenderForward::geometry_instance_set_use_lightmap(GeometryInst GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); ginstance->lightmap_instance = p_lightmap_instance; - ginstance->data->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->data->lightmap_slice_index = p_lightmap_slice_index; + ginstance->lightmap_uv_scale = p_lightmap_uv_scale; + ginstance->lightmap_slice_index = p_lightmap_slice_index; _geometry_instance_mark_dirty(ginstance); } void RendererSceneRenderForward::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { @@ -3067,7 +3258,7 @@ void RendererSceneRenderForward::geometry_instance_set_lightmap_capture(Geometry void RendererSceneRenderForward::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - ginstance->data->shader_parameters_offset = p_offset; + ginstance->shader_parameters_offset = p_offset; _geometry_instance_mark_dirty(ginstance); } void RendererSceneRenderForward::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { @@ -3081,8 +3272,7 @@ void RendererSceneRenderForward::geometry_instance_set_cast_double_sided_shadows void RendererSceneRenderForward::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); - ginstance->data->layer_mask = p_layer_mask; - ginstance->push_constant.layer_mask = p_layer_mask; + ginstance->layer_mask = p_layer_mask; } void RendererSceneRenderForward::geometry_instance_free(GeometryInstance *p_geometry_instance) { @@ -3114,7 +3304,7 @@ void RendererSceneRenderForward::geometry_instance_pair_decal_instances(Geometry Transform RendererSceneRenderForward::geometry_instance_get_transform(GeometryInstance *p_instance) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance); ERR_FAIL_COND_V(!ginstance, Transform()); - return ginstance->data->transform; + return ginstance->transform; } AABB RendererSceneRenderForward::geometry_instance_get_aabb(GeometryInstance *p_instance) { GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance); @@ -3382,18 +3572,13 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor shader.compiler.initialize(actions); } - //render list - render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)128000); - render_list.init(); - render_pass = 0; - - scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); - { //default material and shader - default_shader = storage->shader_create(); + default_shader = storage->shader_allocate(); + storage->shader_initialize(default_shader); storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n"); - default_material = storage->material_create(); + default_material = storage->material_allocate(); + storage->material_initialize(default_material); storage->material_set_shader(default_material, default_shader); MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D); @@ -3404,14 +3589,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor } { - overdraw_material_shader = storage->shader_create(); + overdraw_material_shader = storage->shader_allocate(); + storage->shader_initialize(overdraw_material_shader); storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }"); - overdraw_material = storage->material_create(); + overdraw_material = storage->material_allocate(); + storage->material_initialize(overdraw_material); storage->material_set_shader(overdraw_material, overdraw_material_shader); - wireframe_material_shader = storage->shader_create(); + wireframe_material_shader = storage->shader_allocate(); + storage->shader_initialize(wireframe_material_shader); storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }"); - wireframe_material = storage->material_create(); + wireframe_material = storage->material_allocate(); + storage->material_initialize(wireframe_material); storage->material_set_shader(wireframe_material, wireframe_material_shader); } @@ -3442,8 +3631,10 @@ RendererSceneRenderForward::~RendererSceneRenderForward() { directional_shadow_atlas_set_size(0); //clear base uniform set if still valid - if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) { - RD::get_singleton()->free(render_pass_uniform_set); + for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) { + if (render_pass_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[i])) { + RD::get_singleton()->free(render_pass_uniform_sets[i]); + } } if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) { @@ -3462,9 +3653,16 @@ RendererSceneRenderForward::~RendererSceneRenderForward() { storage->free(default_material); { - RD::get_singleton()->free(scene_state.uniform_buffer); + for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) { + RD::get_singleton()->free(scene_state.uniform_buffers[i]); + } RD::get_singleton()->free(scene_state.lightmap_buffer); RD::get_singleton()->free(scene_state.lightmap_capture_buffer); + for (uint32_t i = 0; i < RENDER_LIST_MAX; i++) { + if (scene_state.instance_buffer[i] != RID()) { + RD::get_singleton()->free(scene_state.instance_buffer[i]); + } + } memdelete_arr(scene_state.lightmap_captures); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h index 0b57c7f76c..af78c50fda 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h @@ -50,6 +50,15 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { MAX_GI_PROBES = 8, MAX_LIGHTMAPS = 8, MAX_GI_PROBES_PER_INSTANCE = 2, + INSTANCE_DATA_BUFFER_MIN_SIZE = 4096 + }; + + enum RenderListType { + RENDER_LIST_OPAQUE, //used for opaque objects + RENDER_LIST_ALPHA, //used for transparent objects + RENDER_LIST_SECONDARY, //used for shadows and other objects + RENDER_LIST_MAX + }; /* Scene Shader */ @@ -245,7 +254,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RID shadow_sampler; RID render_base_uniform_set; - RID render_pass_uniform_set; + LocalVector<RID> render_pass_uniform_sets; RID sdfgi_pass_uniform_set; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -257,7 +266,58 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { void _update_render_base_uniform_set(); RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture); - RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0); + + enum PassMode { + PASS_MODE_COLOR, + PASS_MODE_COLOR_SPECULAR, + PASS_MODE_COLOR_TRANSPARENT, + PASS_MODE_SHADOW, + PASS_MODE_SHADOW_DP, + PASS_MODE_DEPTH, + PASS_MODE_DEPTH_NORMAL_ROUGHNESS, + PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE, + PASS_MODE_DEPTH_MATERIAL, + PASS_MODE_SDF, + }; + + struct GeometryInstanceSurfaceDataCache; + struct RenderElementInfo; + + struct RenderListParameters { + GeometryInstanceSurfaceDataCache **elements = nullptr; + RenderElementInfo *element_info = nullptr; + int element_count = 0; + bool reverse_cull = false; + PassMode pass_mode = PASS_MODE_COLOR; + bool no_gi = false; + RID render_pass_uniform_set; + bool force_wireframe = false; + Vector2 uv_offset; + Plane lod_plane; + float lod_distance_multiplier = 0.0; + float screen_lod_threshold = 0.0; + RD::FramebufferFormatID framebuffer_format = 0; + uint32_t element_offset = 0; + uint32_t barrier = RD::BARRIER_MASK_ALL; + + RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { + elements = p_elements; + element_info = p_element_info; + element_count = p_element_count; + reverse_cull = p_reverse_cull; + pass_mode = p_pass_mode; + no_gi = p_no_gi; + render_pass_uniform_set = p_render_pass_uniform_set; + force_wireframe = p_force_wireframe; + uv_offset = p_uv_offset; + lod_plane = p_lod_plane; + lod_distance_multiplier = p_lod_distance_multiplier; + screen_lod_threshold = p_screen_lod_threshold; + element_offset = p_element_offset; + barrier = p_barrier; + } + }; struct LightmapData { float normal_xform[12]; @@ -367,9 +427,24 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { uint32_t pancake_shadows; }; + struct PushConstant { + uint32_t base_index; // + uint32_t uv_offset; //packed + uint32_t pad[2]; + }; + + struct InstanceData { + float transform[16]; + uint32_t flags; + uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables + uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index) + uint32_t layer_mask; + float lightmap_uv_scale[4]; + }; + UBO ubo; - RID uniform_buffer; + LocalVector<RID> uniform_buffers; LightmapData lightmaps[MAX_LIGHTMAPS]; RID lightmap_ids[MAX_LIGHTMAPS]; @@ -378,6 +453,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { uint32_t max_lightmaps; RID lightmap_buffer; + RID instance_buffer[RENDER_LIST_MAX]; + uint32_t instance_buffer_size[RENDER_LIST_MAX] = { 0, 0, 0 }; + LocalVector<InstanceData> instance_data[RENDER_LIST_MAX]; + LightmapCaptureData *lightmap_captures; uint32_t max_lightmap_captures; RID lightmap_capture_buffer; @@ -390,10 +469,29 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { bool used_depth_texture = false; bool used_sss = false; + struct ShadowPass { + uint32_t element_from; + uint32_t element_count; + bool flip_cull; + PassMode pass_mode; + + RID rp_uniform_set; + Plane camera_plane; + float lod_distance_multiplier; + float screen_lod_threshold; + + RID framebuffer; + RD::InitialAction initial_depth_action; + RD::FinalAction final_depth_action; + Rect2i rect; + }; + + LocalVector<ShadowPass> shadow_passes; + } scene_state; static RendererSceneRenderForward *singleton; - uint64_t render_pass; + double time; RID default_shader; RID default_material; @@ -407,51 +505,15 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RID default_vec4_xform_buffer; RID default_vec4_xform_uniform_set; - enum PassMode { - PASS_MODE_COLOR, - PASS_MODE_COLOR_SPECULAR, - PASS_MODE_COLOR_TRANSPARENT, - PASS_MODE_SHADOW, - PASS_MODE_SHADOW_DP, - PASS_MODE_DEPTH, - PASS_MODE_DEPTH_NORMAL_ROUGHNESS, - PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE, - PASS_MODE_DEPTH_MATERIAL, - PASS_MODE_SDF, - }; - - void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false); + void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); void _setup_giprobes(const PagedArray<RID> &p_giprobes); void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform); - struct GeometryInstanceSurfaceDataCache; - - struct RenderListParameters { - GeometryInstanceSurfaceDataCache **elements = nullptr; - int element_count = 0; - bool reverse_cull = false; - PassMode pass_mode = PASS_MODE_COLOR; - bool no_gi = false; - RID render_pass_uniform_set; - bool force_wireframe = false; - Vector2 uv_offset; - Plane lod_plane; - float lod_distance_multiplier = 0.0; - float screen_lod_threshold = 0.0; - RD::FramebufferFormatID framebuffer_format = 0; - RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) { - elements = p_elements; - element_count = p_element_count; - reverse_cull = p_reverse_cull; - pass_mode = p_pass_mode; - no_gi = p_no_gi; - render_pass_uniform_set = p_render_pass_uniform_set; - force_wireframe = p_force_wireframe; - uv_offset = p_uv_offset; - lod_plane = p_lod_plane; - lod_distance_multiplier = p_lod_distance_multiplier; - screen_lod_threshold = p_screen_lod_threshold; - } + struct RenderElementInfo { + uint32_t repeat : 22; + uint32_t uses_lightmap : 1; + uint32_t uses_forward_gi : 1; + uint32_t lod_index : 8; }; template <PassMode p_pass_mode> @@ -465,7 +527,9 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { uint32_t render_list_thread_threshold = 500; - void _fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false); + void _update_instance_data_buffer(RenderListType p_render_list); + void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); + void _fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false); Map<Size2i, RID> sdfgi_framebuffer_size_cache; @@ -493,14 +557,17 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { union { struct { - uint32_t geometry_id; - uint32_t material_id; - uint32_t shader_id; - uint32_t surface_type : 4; - uint32_t uses_forward_gi : 1; //set during addition - uint32_t uses_lightmap : 1; //set during addition - uint32_t depth_layer : 4; //set during addition - uint32_t priority : 8; + uint64_t lod_index : 8; + uint64_t surface_index : 10; + uint64_t geometry_id : 32; + uint64_t material_id_low : 14; + + uint64_t material_id_hi : 18; + uint64_t shader_id : 32; + uint64_t uses_forward_gi : 1; + uint64_t uses_lightmap : 1; + uint64_t depth_layer : 4; + uint64_t priority : 8; }; struct { uint64_t sort_key1; @@ -532,20 +599,20 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { float lod_model_scale = 1.0; AABB transformed_aabb; //needed for LOD float depth = 0; - struct PushConstant { - float transform[16]; - uint32_t flags; - uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables - uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index) - uint32_t layer_mask; - float lightmap_uv_scale[4]; - } push_constant; + uint32_t gi_offset_cache = 0; + uint32_t flags_cache = 0; + bool store_transform_cache = true; + int32_t shader_parameters_offset = -1; + uint32_t lightmap_slice_index; + Rect2 lightmap_uv_scale; + uint32_t layer_mask = 1; RID transforms_uniform_set; uint32_t instance_count = 0; RID mesh_instance; bool can_sdfgi = false; //used during setup uint32_t base_flags = 0; + Transform transform; RID gi_probes[MAX_GI_PROBES_PER_INSTANCE]; RID lightmap_instance; GeometryInstanceLightmapSH *lightmap_sh = nullptr; @@ -558,21 +625,14 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { RS::InstanceType base_type; RID skeleton; - - uint32_t layer_mask = 1; - Vector<RID> surface_materials; RID material_override; - Transform transform; AABB aabb; - int32_t shader_parameters_offset = -1; bool use_dynamic_gi = false; bool use_baked_light = false; bool cast_double_sided_shaodows = false; bool mirror = false; - Rect2 lightmap_uv_scale; - uint32_t lightmap_slice_index = 0; bool dirty_dependencies = false; RendererStorage::DependencyTracker dependency_tracker; @@ -604,16 +664,12 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { /* Render List */ struct RenderList { - int max_elements; - - GeometryInstanceSurfaceDataCache **elements = nullptr; - - int element_count; - int alpha_element_count; + LocalVector<GeometryInstanceSurfaceDataCache *> elements; + LocalVector<RenderElementInfo> element_info; void clear() { - element_count = 0; - alpha_element_count = 0; + elements.clear(); + element_info.clear(); } //should eventually be replaced by radix @@ -624,13 +680,14 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { } }; - void sort_by_key(bool p_alpha) { + void sort_by_key() { SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + sorter.sort(elements.ptr(), elements.size()); + } + + void sort_by_key_range(uint32_t p_from, uint32_t p_size) { + SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter; + sorter.sort(elements.ptr() + p_from, p_size); } struct SortByDepth { @@ -639,14 +696,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { } }; - void sort_by_depth(bool p_alpha) { //used for shadows + void sort_by_depth() { //used for shadows SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + sorter.sort(elements.ptr(), elements.size()); } struct SortByReverseDepthAndPriority { @@ -658,50 +711,24 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter; - if (p_alpha) { - sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); - } else { - sorter.sort(elements, element_count); - } + sorter.sort(elements.ptr(), elements.size()); } _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) { - if (element_count + alpha_element_count >= max_elements) { - return; - } - elements[element_count] = p_element; - element_count++; - } - - _FORCE_INLINE_ void add_alpha_element(GeometryInstanceSurfaceDataCache *p_element) { - if (element_count + alpha_element_count >= max_elements) { - return; - } - int idx = max_elements - alpha_element_count - 1; - elements[idx] = p_element; - alpha_element_count++; - } - - void init() { - element_count = 0; - alpha_element_count = 0; - elements = memnew_arr(GeometryInstanceSurfaceDataCache *, max_elements); - } - - RenderList() { - max_elements = 0; - } - - ~RenderList() { - memdelete_arr(elements); + elements.push_back(p_element); } }; - RenderList render_list; + RenderList render_list[RENDER_LIST_MAX]; protected: - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold); - virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold); + + virtual void _render_shadow_begin(); + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); + virtual void _render_shadow_process(); + virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL); + virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 1461be8088..74cfd64561 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -667,6 +667,13 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment u.ids.push_back(rb->sdfgi->lightprobe_texture); uniforms.push_back(u); } + { + RD::Uniform u; + u.binding = 11; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.ids.push_back(rb->sdfgi->occlusion_texture); + uniforms.push_back(u); + } cascade.sdf_direct_light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, 0), 0); } @@ -949,7 +956,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment sdfgi->cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 0); } - sdfgi->uses_multibounce = env->sdfgi_use_multibounce; + sdfgi->bounce_feedback = env->sdfgi_bounce_feedback; sdfgi->energy = env->sdfgi_energy; sdfgi->normal_bias = env->sdfgi_normal_bias; sdfgi->probe_bias = env->sdfgi_probe_bias; @@ -962,7 +969,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment //check for updates - sdfgi->uses_multibounce = env->sdfgi_use_multibounce; + sdfgi->bounce_feedback = env->sdfgi_bounce_feedback; sdfgi->energy = env->sdfgi_energy; sdfgi->normal_bias = env->sdfgi_normal_bias; sdfgi->probe_bias = env->sdfgi_probe_bias; @@ -1148,162 +1155,72 @@ void RendererSceneRenderRD::_sdfgi_update_cascades(RID p_render_buffers) { cascade_data[i].pad = 0; } - RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data); + RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); } -void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) { +void RendererSceneRenderRD::_sdfgi_update_light(RID p_render_buffers, RID p_environment) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { return; } - Environment *env = environment_owner.getornull(p_environment); - - RENDER_TIMESTAMP(">SDFGI Update Probes"); - - /* Update Cascades UBO */ - _sdfgi_update_cascades(p_render_buffers); - /* Update Dynamic Lights Buffer */ - - RENDER_TIMESTAMP("Update Lights"); - - /* Update dynamic lights */ - - { - int32_t cascade_light_count[SDFGI::MAX_CASCADES]; - - for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { - SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; - - SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS]; - uint32_t idx = 0; - for (uint32_t j = 0; j < (uint32_t)p_directional_lights.size(); j++) { - if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { - break; - } - LightInstance *li = light_instance_owner.getornull(p_directional_lights[j]); - ERR_CONTINUE(!li); + RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light"); - if (storage->light_directional_is_sky_only(li->light)) { - continue; - } + /* Update dynamic light */ - Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); - dir.y *= rb->sdfgi->y_mult; - dir.normalize(); - lights[idx].direction[0] = dir.x; - lights[idx].direction[1] = dir.y; - lights[idx].direction[2] = dir.z; - Color color = storage->light_get_color(li->light); - color = color.to_linear(); - lights[idx].color[0] = color.r; - lights[idx].color[1] = color.g; - lights[idx].color[2] = color.b; - lights[idx].type = RS::LIGHT_DIRECTIONAL; - lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); - lights[idx].has_shadow = storage->light_has_shadow(li->light); - - idx++; - } - - AABB cascade_aabb; - cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + cascade.position)) * cascade.cell_size; - cascade_aabb.size = Vector3(1, 1, 1) * rb->sdfgi->cascade_size * cascade.cell_size; - - for (uint32_t j = 0; j < p_positional_light_count; j++) { - if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { - break; - } - - LightInstance *li = light_instance_owner.getornull(p_positional_light_instances[j]); - ERR_CONTINUE(!li); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_DYNAMIC]); - uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light); - if (i > max_sdfgi_cascade) { - continue; - } + SDGIShader::DirectLightPushConstant push_constant; - if (!cascade_aabb.intersects(li->aabb)) { - continue; - } + push_constant.grid_size[0] = rb->sdfgi->cascade_size; + push_constant.grid_size[1] = rb->sdfgi->cascade_size; + push_constant.grid_size[2] = rb->sdfgi->cascade_size; + push_constant.max_cascades = rb->sdfgi->cascades.size(); + push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; + push_constant.bounce_feedback = rb->sdfgi->bounce_feedback; + push_constant.y_mult = rb->sdfgi->y_mult; + push_constant.use_occlusion = rb->sdfgi->uses_occlusion; - Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); - //faster to not do this here - //dir.y *= rb->sdfgi->y_mult; - //dir.normalize(); - lights[idx].direction[0] = dir.x; - lights[idx].direction[1] = dir.y; - lights[idx].direction[2] = dir.z; - Vector3 pos = li->transform.origin; - pos.y *= rb->sdfgi->y_mult; - lights[idx].position[0] = pos.x; - lights[idx].position[1] = pos.y; - lights[idx].position[2] = pos.z; - Color color = storage->light_get_color(li->light); - color = color.to_linear(); - lights[idx].color[0] = color.r; - lights[idx].color[1] = color.g; - lights[idx].color[2] = color.b; - lights[idx].type = storage->light_get_type(li->light); - lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); - lights[idx].has_shadow = storage->light_has_shadow(li->light); - lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); - lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); - lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)); - lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { + SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; + push_constant.light_count = rb->sdfgi->cascade_dynamic_light_count[i]; + push_constant.cascade = i; - idx++; - } + if (rb->sdfgi->cascades[i].all_dynamic_lights_dirty || sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) { + push_constant.process_offset = 0; + push_constant.process_increment = 1; + } else { + static uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = { + 1, 2, 4, 8, 16 + }; - if (idx > 0) { - RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights); - } + uint32_t frames_to_update = frames_to_update_table[sdfgi_frames_to_update_light]; - cascade_light_count[i] = idx; + push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update; + push_constant.process_increment = frames_to_update; } + rb->sdfgi->cascades[i].all_dynamic_lights_dirty = false; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_DYNAMIC]); - - SDGIShader::DirectLightPushConstant push_constant; - - push_constant.grid_size[0] = rb->sdfgi->cascade_size; - push_constant.grid_size[1] = rb->sdfgi->cascade_size; - push_constant.grid_size[2] = rb->sdfgi->cascade_size; - push_constant.max_cascades = rb->sdfgi->cascades.size(); - push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; - push_constant.multibounce = rb->sdfgi->uses_multibounce; - push_constant.y_mult = rb->sdfgi->y_mult; - - for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { - SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; - push_constant.light_count = cascade_light_count[i]; - push_constant.cascade = i; - - if (rb->sdfgi->cascades[i].all_dynamic_lights_dirty || sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) { - push_constant.process_offset = 0; - push_constant.process_increment = 1; - } else { - static uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = { - 1, 2, 4, 8, 16 - }; - - uint32_t frames_to_update = frames_to_update_table[sdfgi_frames_to_update_light]; - - push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update; - push_constant.process_increment = frames_to_update; - } - rb->sdfgi->cascades[i].all_dynamic_lights_dirty = false; + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant)); + RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0); + } + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); + RD::get_singleton()->draw_command_end_label(); +} - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant)); - RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0); - } - RD::get_singleton()->compute_list_end(); +void RendererSceneRenderRD::_sdfgi_update_probes(RID p_render_buffers, RID p_environment) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(rb == nullptr); + if (rb->sdfgi == nullptr) { + return; } - RENDER_TIMESTAMP("Raytrace"); + RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes"); + + Environment *env = environment_owner.getornull(p_environment); SDGIShader::IntegratePushConstant push_constant; push_constant.grid_size[1] = rb->sdfgi->cascade_size; @@ -1372,7 +1289,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi rb->sdfgi->render_pass++; - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_PROCESS]); int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR; @@ -1386,14 +1303,47 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1); } - RD::get_singleton()->compute_list_add_barrier(compute_list); //wait until done + //end later after raster to avoid barriering on layout changes + //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); + + RD::get_singleton()->draw_command_end_label(); +} + +void RendererSceneRenderRD::_sdfgi_store_probes(RID p_render_buffers) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(rb == nullptr); + if (rb->sdfgi == nullptr) { + return; + } + + RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE); + RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes"); + + SDGIShader::IntegratePushConstant push_constant; + push_constant.grid_size[1] = rb->sdfgi->cascade_size; + push_constant.grid_size[2] = rb->sdfgi->cascade_size; + push_constant.grid_size[0] = rb->sdfgi->cascade_size; + push_constant.max_cascades = rb->sdfgi->cascades.size(); + push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; + push_constant.history_index = rb->sdfgi->render_pass % rb->sdfgi->history_size; + push_constant.history_size = rb->sdfgi->history_size; + static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 }; + push_constant.ray_count = ray_count[sdfgi_ray_count]; + push_constant.ray_bias = rb->sdfgi->probe_bias; + push_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count; + push_constant.image_size[1] = rb->sdfgi->probe_axis_count; + push_constant.store_ambient_texture = false; + + push_constant.sky_mode = 0; + push_constant.y_mult = rb->sdfgi->y_mult; // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces RENDER_TIMESTAMP("Average Probes"); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]); //convert to octahedral to store @@ -1403,20 +1353,22 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { push_constant.cascade = i; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[i].integrate_uniform_set, 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1); } - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); - RENDER_TIMESTAMP("<SDFGI Update Probes"); + RD::get_singleton()->draw_command_end_label(); } - void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used) { r_gi_probes_used = 0; RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); + RD::get_singleton()->draw_command_begin_label("GIProbes Setup"); + RID gi_probe_buffer = render_buffers_get_gi_probe_buffer(p_render_buffers); GI::GIProbeData gi_probe_data[RenderBuffers::MAX_GIPROBES]; @@ -1500,80 +1452,25 @@ void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transfor } if (p_gi_probes.size() > 0) { - RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data); + RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, RD::BARRIER_MASK_COMPUTE); } -} -void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) { - RENDER_TIMESTAMP("Render GI"); + RD::get_singleton()->draw_command_end_label(); +} +void RendererSceneRenderRD::_pre_process_gi(RID p_render_buffers, const Transform &p_transform) { + // Do the required buffer transfers and setup before the depth-pre pass, this way GI can + // run in parallel during depth-pre pass and shadow rendering. RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(rb == nullptr); - Environment *env = environment_owner.getornull(p_environment); - - if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != gi.half_resolution) { - if (rb->ambient_buffer.is_valid()) { - RD::get_singleton()->free(rb->ambient_buffer); - RD::get_singleton()->free(rb->reflection_buffer); - } - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.width = rb->width; - tf.height = rb->height; - if (gi.half_resolution) { - tf.width >>= 1; - tf.height >>= 1; - } - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->using_half_size_gi = gi.half_resolution; - - _render_buffers_uniform_set_changed(p_render_buffers); - } - - GI::PushConstant push_constant; - - push_constant.screen_size[0] = rb->width; - push_constant.screen_size[1] = rb->height; - push_constant.z_near = p_projection.get_z_near(); - push_constant.z_far = p_projection.get_z_far(); - push_constant.orthogonal = p_projection.is_orthogonal(); - push_constant.proj_info[0] = -2.0f / (rb->width * p_projection.matrix[0][0]); - push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]); - push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0]; - push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1]; - push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()); - push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH; + /* Update Cascades UBO */ - bool use_sdfgi = rb->sdfgi != nullptr; - bool use_giprobes = push_constant.max_giprobes > 0; + if (rb->sdfgi) { + /* Update general SDFGI Buffer */ - if (env) { - push_constant.ao_color[0] = env->ao_color.r; - push_constant.ao_color[1] = env->ao_color.g; - push_constant.ao_color[2] = env->ao_color.b; - } else { - push_constant.ao_color[0] = 0; - push_constant.ao_color[1] = 0; - push_constant.ao_color[2] = 0; - } + _sdfgi_update_cascades(p_render_buffers); - push_constant.cam_rotation[0] = p_transform.basis[0][0]; - push_constant.cam_rotation[1] = p_transform.basis[1][0]; - push_constant.cam_rotation[2] = p_transform.basis[2][0]; - push_constant.cam_rotation[3] = 0; - push_constant.cam_rotation[4] = p_transform.basis[0][1]; - push_constant.cam_rotation[5] = p_transform.basis[1][1]; - push_constant.cam_rotation[6] = p_transform.basis[2][1]; - push_constant.cam_rotation[7] = 0; - push_constant.cam_rotation[8] = p_transform.basis[0][2]; - push_constant.cam_rotation[9] = p_transform.basis[1][2]; - push_constant.cam_rotation[10] = p_transform.basis[2][2]; - push_constant.cam_rotation[11] = 0; - - if (rb->sdfgi) { GI::SDFGIData sdfgi_data; sdfgi_data.grid_size[0] = rb->sdfgi->cascade_size; @@ -1640,8 +1537,171 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough c.to_cell = 1.0 / rb->sdfgi->cascades[i].cell_size; } - RD::get_singleton()->buffer_update(gi.sdfgi_ubo, 0, sizeof(GI::SDFGIData), &sdfgi_data); + RD::get_singleton()->buffer_update(gi.sdfgi_ubo, 0, sizeof(GI::SDFGIData), &sdfgi_data, RD::BARRIER_MASK_COMPUTE); + + /* Update dynamic lights in SDFGI cascades */ + + for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) { + SDFGI::Cascade &cascade = rb->sdfgi->cascades[i]; + + SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS]; + uint32_t idx = 0; + for (uint32_t j = 0; j < (uint32_t)render_state.sdfgi_update_data->directional_lights->size(); j++) { + if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { + break; + } + + LightInstance *li = light_instance_owner.getornull(render_state.sdfgi_update_data->directional_lights->get(j)); + ERR_CONTINUE(!li); + + if (storage->light_directional_is_sky_only(li->light)) { + continue; + } + + Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); + dir.y *= rb->sdfgi->y_mult; + dir.normalize(); + lights[idx].direction[0] = dir.x; + lights[idx].direction[1] = dir.y; + lights[idx].direction[2] = dir.z; + Color color = storage->light_get_color(li->light); + color = color.to_linear(); + lights[idx].color[0] = color.r; + lights[idx].color[1] = color.g; + lights[idx].color[2] = color.b; + lights[idx].type = RS::LIGHT_DIRECTIONAL; + lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); + lights[idx].has_shadow = storage->light_has_shadow(li->light); + + idx++; + } + + AABB cascade_aabb; + cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + cascade.position)) * cascade.cell_size; + cascade_aabb.size = Vector3(1, 1, 1) * rb->sdfgi->cascade_size * cascade.cell_size; + + for (uint32_t j = 0; j < render_state.sdfgi_update_data->positional_light_count; j++) { + if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { + break; + } + + LightInstance *li = light_instance_owner.getornull(render_state.sdfgi_update_data->positional_light_instances[j]); + ERR_CONTINUE(!li); + + uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light); + if (i > max_sdfgi_cascade) { + continue; + } + + if (!cascade_aabb.intersects(li->aabb)) { + continue; + } + + Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z); + //faster to not do this here + //dir.y *= rb->sdfgi->y_mult; + //dir.normalize(); + lights[idx].direction[0] = dir.x; + lights[idx].direction[1] = dir.y; + lights[idx].direction[2] = dir.z; + Vector3 pos = li->transform.origin; + pos.y *= rb->sdfgi->y_mult; + lights[idx].position[0] = pos.x; + lights[idx].position[1] = pos.y; + lights[idx].position[2] = pos.z; + Color color = storage->light_get_color(li->light); + color = color.to_linear(); + lights[idx].color[0] = color.r; + lights[idx].color[1] = color.g; + lights[idx].color[2] = color.b; + lights[idx].type = storage->light_get_type(li->light); + lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY); + lights[idx].has_shadow = storage->light_has_shadow(li->light); + lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); + lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); + lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE))); + lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + + idx++; + } + + if (idx > 0) { + RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, RD::BARRIER_MASK_COMPUTE); + } + + rb->sdfgi->cascade_dynamic_light_count[i] = idx; + } } +} + +void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) { + RD::get_singleton()->draw_command_begin_label("GI Render"); + + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(rb == nullptr); + Environment *env = environment_owner.getornull(p_environment); + + if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != gi.half_resolution) { + if (rb->ambient_buffer.is_valid()) { + RD::get_singleton()->free(rb->ambient_buffer); + RD::get_singleton()->free(rb->reflection_buffer); + } + + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = rb->width; + tf.height = rb->height; + if (gi.half_resolution) { + tf.width >>= 1; + tf.height >>= 1; + } + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->using_half_size_gi = gi.half_resolution; + + _render_buffers_uniform_set_changed(p_render_buffers); + } + + GI::PushConstant push_constant; + + push_constant.screen_size[0] = rb->width; + push_constant.screen_size[1] = rb->height; + push_constant.z_near = p_projection.get_z_near(); + push_constant.z_far = p_projection.get_z_far(); + push_constant.orthogonal = p_projection.is_orthogonal(); + push_constant.proj_info[0] = -2.0f / (rb->width * p_projection.matrix[0][0]); + push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]); + push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0]; + push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1]; + push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()); + push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH; + + bool use_sdfgi = rb->sdfgi != nullptr; + bool use_giprobes = push_constant.max_giprobes > 0; + + if (env) { + push_constant.ao_color[0] = env->ao_color.r; + push_constant.ao_color[1] = env->ao_color.g; + push_constant.ao_color[2] = env->ao_color.b; + } else { + push_constant.ao_color[0] = 0; + push_constant.ao_color[1] = 0; + push_constant.ao_color[2] = 0; + } + + push_constant.cam_rotation[0] = p_transform.basis[0][0]; + push_constant.cam_rotation[1] = p_transform.basis[1][0]; + push_constant.cam_rotation[2] = p_transform.basis[2][0]; + push_constant.cam_rotation[3] = 0; + push_constant.cam_rotation[4] = p_transform.basis[0][1]; + push_constant.cam_rotation[5] = p_transform.basis[1][1]; + push_constant.cam_rotation[6] = p_transform.basis[2][1]; + push_constant.cam_rotation[7] = 0; + push_constant.cam_rotation[8] = p_transform.basis[0][2]; + push_constant.cam_rotation[9] = p_transform.basis[1][2]; + push_constant.cam_rotation[10] = p_transform.basis[2][2]; + push_constant.cam_rotation[11] = 0; if (rb->gi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) { Vector<RD::Uniform> uniforms; @@ -1806,21 +1866,26 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough } else { mode = (use_sdfgi && use_giprobes) ? GI::MODE_COMBINED : (use_sdfgi ? GI::MODE_SDFGI : GI::MODE_GIPROBE); } - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi.pipelines[mode]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GI::PushConstant)); if (rb->using_half_size_gi) { - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1); } else { - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1); } - RD::get_singleton()->compute_list_end(); + //do barrier later to allow oeverlap + //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time + RD::get_singleton()->draw_command_end_label(); } -RID RendererSceneRenderRD::sky_create() { - return sky_owner.make_rid(Sky()); +RID RendererSceneRenderRD::sky_allocate() { + return sky_owner.allocate_rid(); +} +void RendererSceneRenderRD::sky_initialize(RID p_rid) { + sky_owner.initialize_rid(p_rid, Sky()); } void RendererSceneRenderRD::_sky_invalidate(Sky *p_sky) { @@ -2844,8 +2909,11 @@ RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_sky_material_fun return material_data; } -RID RendererSceneRenderRD::environment_create() { - return environment_owner.make_rid(Environment()); +RID RendererSceneRenderRD::environment_allocate() { + return environment_owner.allocate_rid(); +} +void RendererSceneRenderRD::environment_initialize(RID p_rid) { + environment_owner.initialize_rid(p_rid, Environment()); } void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { @@ -3019,7 +3087,7 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) glow_high_quality = p_enable; } -void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { +void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3031,7 +3099,7 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS:: env->sdfgi_cascades = p_cascades; env->sdfgi_min_cell_size = p_min_cell_size; env->sdfgi_use_occlusion = p_use_occlusion; - env->sdfgi_use_multibounce = p_use_multibounce; + env->sdfgi_bounce_feedback = p_bounce_feedback; env->sdfgi_read_sky_light = p_read_sky; env->sdfgi_energy = p_energy; env->sdfgi_normal_bias = p_normal_bias; @@ -3097,7 +3165,7 @@ float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) c return env->fog_aerial_perspective; } -void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) { +void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -3111,8 +3179,9 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena env->volumetric_fog_light_energy = p_light_energy; env->volumetric_fog_length = p_length; env->volumetric_fog_detail_spread = p_detail_spread; - env->volumetric_fog_shadow_filter = p_shadow_filter; env->volumetric_fog_gi_inject = p_gi_inject; + env->volumetric_fog_temporal_reprojection = p_temporal_reprojection; + env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; } void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { @@ -3123,25 +3192,6 @@ void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_siz void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) { volumetric_fog_filter_active = p_enable; } -void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) { - p_shrink_size = nearest_power_of_2_templated(p_shrink_size); - if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) { - return; - } - - _clear_shadow_shrink_stages(directional_shadow.shrink_stages); -} -void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) { - p_shrink_size = nearest_power_of_2_templated(p_shrink_size); - if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) { - return; - } - - for (uint32_t i = 0; i < shadow_atlas_owner.get_rid_count(); i++) { - ShadowAtlas *sa = shadow_atlas_owner.get_ptr_by_index(i); - _clear_shadow_shrink_stages(sa->shrink_stages); - } -} void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { sdfgi_ray_count = p_ray_count; @@ -3593,7 +3643,6 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool if (shadow_atlas->depth.is_valid()) { RD::get_singleton()->free(shadow_atlas->depth); shadow_atlas->depth = RID(); - _clear_shadow_shrink_stages(shadow_atlas->shrink_stages); } for (int i = 0; i < 4; i++) { //clear subdivisions @@ -3892,7 +3941,6 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); - _clear_shadow_shrink_stages(directional_shadow.shrink_stages); directional_shadow.depth = RID(); _base_uniforms_changed(); } @@ -3949,8 +3997,11 @@ int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance ////////////////////////////////////////////////// -RID RendererSceneRenderRD::camera_effects_create() { - return camera_effects_owner.make_rid(CameraEffects()); +RID RendererSceneRenderRD::camera_effects_allocate() { + return camera_effects_owner.allocate_rid(); +} +void RendererSceneRenderRD::camera_effects_initialize(RID p_rid) { + camera_effects_owner.initialize_rid(p_rid, CameraEffects()); } void RendererSceneRenderRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { @@ -4015,11 +4066,7 @@ void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_inst LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); - if (storage->light_get_type(light_instance->light) != RS::LIGHT_DIRECTIONAL) { - p_pass = 0; - } - - ERR_FAIL_INDEX(p_pass, 4); + ERR_FAIL_INDEX(p_pass, 6); light_instance->shadow_transform[p_pass].camera = p_projection; light_instance->shadow_transform[p_pass].transform = p_transform; @@ -4509,8 +4556,8 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins l.color[1] = color.g; l.color[2] = color.b; - l.spot_angle_radians = Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)); - l.spot_attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); + l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); Transform xform = light_instance_get_base_transform(light_instance); @@ -4929,7 +4976,7 @@ void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawLi push_constant.band_power = 4; push_constant.sections_in_band = ((band_points / 2) - 1); push_constant.band_mask = band_points - 2; - push_constant.section_arc = (Math_PI * 2.0) / float(push_constant.sections_in_band); + push_constant.section_arc = Math_TAU / float(push_constant.sections_in_band); push_constant.y_mult = rb->sdfgi->y_mult; uint32_t total_points = push_constant.sections_in_band * band_points; @@ -5150,9 +5197,6 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { RD::get_singleton()->free(rb->luminance.reduce[i]); } - for (int i = 0; i < rb->luminance.reduce.size(); i++) { - RD::get_singleton()->free(rb->luminance.reduce[i]); - } rb->luminance.reduce.clear(); if (rb->luminance.current.is_valid()) { @@ -5767,7 +5811,7 @@ void RendererSceneRenderRD::_sdfgi_debug_draw(RID p_render_buffers, const Camera RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DebugPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1); RD::get_singleton()->compute_list_end(); Size2 rtsize = storage->render_target_get_size(rb->render_target); @@ -6179,7 +6223,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti } if (cluster.reflection_count) { - RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, cluster.reflection_count * sizeof(ReflectionData), cluster.reflections); + RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, cluster.reflection_count * sizeof(ReflectionData), cluster.reflections, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } } @@ -6431,8 +6475,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance; RID base = li->light; - cluster.lights_instances[i] = li->self; - Transform light_transform = li->transform; float sign = storage->light_is_negative(base) ? -1 : 1; @@ -6466,9 +6508,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.size = size; - light_data.cone_attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION); + light_data.inv_spot_attenuation = 1.0f / storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION); float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE); - light_data.cone_angle = Math::cos(Math::deg2rad(spot_angle)); + light_data.cos_spot_angle = Math::cos(Math::deg2rad(spot_angle)); light_data.mask = storage->light_get_cull_mask(base); @@ -6571,16 +6613,17 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const r_positional_light_count++; } + //update without barriers if (cluster.omni_light_count) { - RD::get_singleton()->buffer_update(cluster.omni_light_buffer, 0, sizeof(Cluster::LightData) * cluster.omni_light_count, cluster.omni_lights); + RD::get_singleton()->buffer_update(cluster.omni_light_buffer, 0, sizeof(Cluster::LightData) * cluster.omni_light_count, cluster.omni_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } if (cluster.spot_light_count) { - RD::get_singleton()->buffer_update(cluster.spot_light_buffer, 0, sizeof(Cluster::LightData) * cluster.spot_light_count, cluster.spot_lights); + RD::get_singleton()->buffer_update(cluster.spot_light_buffer, 0, sizeof(Cluster::LightData) * cluster.spot_light_count, cluster.spot_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } if (r_directional_light_count) { - RD::get_singleton()->buffer_update(cluster.directional_light_buffer, 0, sizeof(Cluster::DirectionalLightData) * r_directional_light_count, cluster.directional_lights); + RD::get_singleton()->buffer_update(cluster.directional_light_buffer, 0, sizeof(Cluster::DirectionalLightData) * r_directional_light_count, cluster.directional_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } } @@ -6741,13 +6784,14 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const } if (cluster.decal_count > 0) { - RD::get_singleton()->buffer_update(cluster.decal_buffer, 0, sizeof(Cluster::DecalData) * cluster.decal_count, cluster.decals); + RD::get_singleton()->buffer_update(cluster.decal_buffer, 0, sizeof(Cluster::DecalData) * cluster.decal_count, cluster.decals, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } } void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { ERR_FAIL_COND(!rb->volumetric_fog); + RD::get_singleton()->free(rb->volumetric_fog->prev_light_density_map); RD::get_singleton()->free(rb->volumetric_fog->light_density_map); RD::get_singleton()->free(rb->volumetric_fog->fog_map); @@ -6769,49 +6813,6 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { rb->volumetric_fog = nullptr; } -void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) { - //create fog mipmaps - uint32_t fog_texture_size = p_target_size; - uint32_t base_texture_size = p_base_size; - - ShadowShrinkStage first; - first.size = base_texture_size; - first.texture = p_base; - shrink_stages.push_back(first); //put depth first in case we dont find smaller ones - - while (fog_texture_size < base_texture_size) { - base_texture_size = MAX(base_texture_size / 8, fog_texture_size); - - ShadowShrinkStage s; - s.size = base_texture_size; - - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = base_texture_size; - tf.height = base_texture_size; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; - - if (base_texture_size == fog_texture_size) { - s.filter_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; - } - - s.texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - - shrink_stages.push_back(s); - } -} - -void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) { - for (int i = 1; i < shrink_stages.size(); i++) { - RD::get_singleton()->free(shrink_stages[i].texture); - if (shrink_stages[i].filter_texture.is_valid()) { - RD::get_singleton()->free(shrink_stages[i].filter_texture); - } - } - shrink_stages.clear(); -} - void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -6834,6 +6835,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e return; } + RENDER_TIMESTAMP(">Volumetric Fog"); + if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { //required volumetric fog but not existing, create rb->volumetric_fog = memnew(VolumetricFog); @@ -6847,11 +6850,16 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e tf.height = target_height; tf.depth = volumetric_fog_depth; tf.texture_type = RD::TEXTURE_TYPE_3D; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + + rb->volumetric_fog->prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->texture_clear(rb->volumetric_fog->prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); _render_buffers_uniform_set_changed(p_render_buffers); @@ -6868,164 +6876,6 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG); } - //update directional shadow - - if (p_use_directional_shadows) { - if (directional_shadow.shrink_stages.is_empty()) { - if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { - //invalidate uniform set, we will need a new one - RD::get_singleton()->free(rb->volumetric_fog->uniform_set); - rb->volumetric_fog->uniform_set = RID(); - } - _allocate_shadow_shrink_stages(directional_shadow.depth, directional_shadow.size, directional_shadow.shrink_stages, volumetric_fog_directional_shadow_shrink); - } - - if (directional_shadow.shrink_stages.size() > 1) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - for (int i = 1; i < directional_shadow.shrink_stages.size(); i++) { - int32_t src_size = directional_shadow.shrink_stages[i - 1].size; - int32_t dst_size = directional_shadow.shrink_stages[i].size; - Rect2i r(0, 0, src_size, src_size); - int32_t shrink_limit = 8 / (src_size / dst_size); - - storage->get_effects()->reduce_shadow(directional_shadow.shrink_stages[i - 1].texture, directional_shadow.shrink_stages[i].texture, Size2i(src_size, src_size), r, shrink_limit, compute_list); - RD::get_singleton()->compute_list_add_barrier(compute_list); - if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && directional_shadow.shrink_stages[i].filter_texture.is_valid()) { - Rect2i rf(0, 0, dst_size, dst_size); - storage->get_effects()->filter_shadow(directional_shadow.shrink_stages[i].texture, directional_shadow.shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), rf, env->volumetric_fog_shadow_filter, compute_list); - } - } - RD::get_singleton()->compute_list_end(); - } - } - - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); - - if (shadow_atlas) { - //shrink shadows that need to be shrunk - - bool force_shrink_shadows = false; - - if (shadow_atlas->shrink_stages.is_empty()) { - if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { - //invalidate uniform set, we will need a new one - RD::get_singleton()->free(rb->volumetric_fog->uniform_set); - rb->volumetric_fog->uniform_set = RID(); - } - _allocate_shadow_shrink_stages(shadow_atlas->depth, shadow_atlas->size, shadow_atlas->shrink_stages, volumetric_fog_positional_shadow_shrink); - force_shrink_shadows = true; - } - - if (rb->volumetric_fog->last_shadow_filter != env->volumetric_fog_shadow_filter) { - //if shadow filter changed, invalidate caches - rb->volumetric_fog->last_shadow_filter = env->volumetric_fog_shadow_filter; - force_shrink_shadows = true; - } - - cluster.lights_shadow_rect_cache_count = 0; - - for (uint32_t i = 0; i < cluster.omni_light_count + cluster.spot_light_count; i++) { - Cluster::LightData &ld = i < cluster.omni_light_count ? cluster.omni_lights[i] : cluster.spot_lights[i - cluster.omni_light_count]; - - if (ld.shadow_enabled != 0) { - RID li = cluster.lights_instances[i]; - - ERR_CONTINUE(!shadow_atlas->shadow_owners.has(li)); - - uint32_t key = shadow_atlas->shadow_owners[li]; - - uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; - uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK; - - ERR_CONTINUE((int)shadow >= shadow_atlas->quadrants[quadrant].shadows.size()); - - ShadowAtlas::Quadrant::Shadow &s = shadow_atlas->quadrants[quadrant].shadows.write[shadow]; - - if (!force_shrink_shadows && s.fog_version == s.version) { - continue; //do not update, no need - } - - s.fog_version = s.version; - - uint32_t quadrant_size = shadow_atlas->size >> 1; - - Rect2i atlas_rect; - - atlas_rect.position.x = (quadrant & 1) * quadrant_size; - atlas_rect.position.y = (quadrant >> 1) * quadrant_size; - - uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision); - atlas_rect.position.x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; - atlas_rect.position.y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size; - - atlas_rect.size.x = shadow_size; - atlas_rect.size.y = shadow_size; - - cluster.lights_shadow_rect_cache[cluster.lights_shadow_rect_cache_count] = atlas_rect; - - cluster.lights_shadow_rect_cache_count++; - - if (cluster.lights_shadow_rect_cache_count == cluster.max_lights * 2) { - break; //light limit reached - } - } - } - - if (cluster.lights_shadow_rect_cache_count > 0) { - //there are shadows to be shrunk, try to do them in parallel - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - for (int i = 1; i < shadow_atlas->shrink_stages.size(); i++) { - int32_t base_size = shadow_atlas->shrink_stages[0].size; - int32_t src_size = shadow_atlas->shrink_stages[i - 1].size; - int32_t dst_size = shadow_atlas->shrink_stages[i].size; - - uint32_t rect_divisor = base_size / src_size; - - int32_t shrink_limit = 8 / (src_size / dst_size); - - //shrink in parallel for more performance - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i src_rect = cluster.lights_shadow_rect_cache[j]; - - src_rect.position /= rect_divisor; - src_rect.size /= rect_divisor; - - storage->get_effects()->reduce_shadow(shadow_atlas->shrink_stages[i - 1].texture, shadow_atlas->shrink_stages[i].texture, Size2i(src_size, src_size), src_rect, shrink_limit, compute_list); - } - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && shadow_atlas->shrink_stages[i].filter_texture.is_valid()) { - uint32_t filter_divisor = base_size / dst_size; - - //filter in parallel for more performance - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i dst_rect = cluster.lights_shadow_rect_cache[j]; - - dst_rect.position /= filter_divisor; - dst_rect.size /= filter_divisor; - - storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, true, false); - } - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) { - Rect2i dst_rect = cluster.lights_shadow_rect_cache[j]; - - dst_rect.position /= filter_divisor; - dst_rect.size /= filter_divisor; - - storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, false, true); - } - } - } - - RD::get_singleton()->compute_list_end(); - } - } - //update volumetric fog if (rb->volumetric_fog->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) { @@ -7037,10 +6887,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) { + ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { - u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture); + u.ids.push_back(shadow_atlas->depth); } uniforms.push_back(u); @@ -7050,10 +6901,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - if (directional_shadow.shrink_stages.size() == 0) { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + if (directional_shadow.depth.is_valid()) { + u.ids.push_back(directional_shadow.depth); } else { - u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture); + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); } @@ -7152,6 +7003,13 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.ids.push_back(volumetric_fog.params_ubo); uniforms.push_back(u); } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 15; + u.ids.push_back(rb->volumetric_fog->prev_light_density_map); + uniforms.push_back(u); + } rb->volumetric_fog->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, 0), 0); @@ -7253,6 +7111,13 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e params.cam_rotation[11] = 0; params.filter_axis = 0; params.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0; + params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; + + Transform to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform; + storage->store_transform(to_prev_cam_view, params.to_prev_view); + + params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; + params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; { uint32_t cluster_size = rb->cluster_builder->get_cluster_size(); @@ -7273,10 +7138,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e push_constant.directional_shadow_pixel_size[1] = 1.0 / dssize.y; */ - RENDER_TIMESTAMP(">Volumetric Fog"); + RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog"); RENDER_TIMESTAMP("Render Fog"); - RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms); + RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -7289,17 +7154,25 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (using_sdfgi) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); } - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); + + RD::get_singleton()->draw_command_end_label(); - RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->compute_list_end(); + + RD::get_singleton()->texture_copy(rb->volumetric_fog->light_density_map, rb->volumetric_fog->prev_light_density_map, Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 0, 0, 0, 0); + + compute_list = RD::get_singleton()->compute_list_begin(); if (use_filter) { + RD::get_singleton()->draw_command_begin_label("Filter Fog"); + RENDER_TIMESTAMP("Filter Fog"); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FILTER]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); RD::get_singleton()->compute_list_end(); //need restart for buffer update @@ -7313,95 +7186,176 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (using_sdfgi) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1); } - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); RD::get_singleton()->compute_list_add_barrier(compute_list); + RD::get_singleton()->draw_command_end_label(); } RENDER_TIMESTAMP("Integrate Fog"); + RD::get_singleton()->draw_command_begin_label("Integrate Fog"); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FOG]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1); - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); RENDER_TIMESTAMP("<Volumetric Fog"); + RD::get_singleton()->draw_command_end_label(); + + rb->volumetric_fog->prev_cam_transform = p_cam_transform; } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) { - Color clear_color; - if (p_render_buffers.is_valid()) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); - ERR_FAIL_COND(!rb); - clear_color = storage->render_target_get_clear_request_color(rb->render_target); - } else { - clear_color = storage->get_default_clear_color(); +uint32_t RendererSceneRenderRD::_get_render_state_directional_light_count() const { + return render_state.directional_light_count; +} + +bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) { + if (render_state.render_buffers.is_valid()) { + RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); + if (rb->sdfgi != nullptr) { + return true; + } } + return false; +} - //assign render indices to giprobes - for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) { - GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]); - if (giprobe_inst) { - giprobe_inst->render_index = i; +void RendererSceneRenderRD::_post_prepass_render(bool p_use_gi) { + if (render_state.render_buffers.is_valid()) { + if (p_use_gi) { + _sdfgi_update_probes(render_state.render_buffers, render_state.environment); } } +} - const PagedArray<RID> *lights = &p_lights; - const PagedArray<RID> *reflections = &p_reflection_probes; - const PagedArray<RID> *gi_probes = &p_gi_probes; +void RendererSceneRenderRD::_pre_resolve_render(bool p_use_gi) { + if (render_state.render_buffers.is_valid()) { + if (p_use_gi) { + RD::get_singleton()->compute_list_end(); + } + } +} - PagedArray<RID> empty; +void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) { + // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - lights = ∅ - reflections = ∅ - gi_probes = ∅ + if (render_state.render_buffers.is_valid() && p_use_gi) { + _sdfgi_store_probes(render_state.render_buffers); } - if (render_buffers_owner.owns(p_render_buffers)) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); - current_cluster_builder = rb->cluster_builder; - } else if (reflection_probe_instance_owner.owns(p_reflection_probe)) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflection_probe); - ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas); - if (!ra) { - ERR_PRINT("reflection probe has no reflection atlas! Bug?"); - current_cluster_builder = nullptr; - } else { - current_cluster_builder = ra->cluster_builder; + render_state.cube_shadows.clear(); + render_state.shadows.clear(); + render_state.directional_shadows.clear(); + + Plane camera_plane(render_state.cam_transform.origin, -render_state.cam_transform.basis.get_axis(Vector3::AXIS_Z)); + float lod_distance_multiplier = render_state.cam_projection.get_lod_multiplier(); + + { + for (int i = 0; i < render_state.render_shadow_count; i++) { + LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light); + + if (storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) { + render_state.directional_shadows.push_back(i); + } else if (storage->light_get_type(li->light) == RS::LIGHT_OMNI && storage->light_omni_get_shadow_mode(li->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { + render_state.cube_shadows.push_back(i); + } else { + render_state.shadows.push_back(i); + } } - } else { - ERR_PRINT("No cluster builder, bug"); //should never happen, will crash - current_cluster_builder = nullptr; + + //cube shadows are rendered in their own way + for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) { + _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, true, true, true); + } + + if (render_state.directional_shadows.size()) { + //open the pass for directional shadows + _update_directional_shadow_atlas(); + RD::get_singleton()->draw_list_begin(directional_shadow.fb, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE); + RD::get_singleton()->draw_list_end(); + } + } + + // Render GI + + bool render_shadows = render_state.directional_shadows.size() || render_state.shadows.size(); + bool render_gi = render_state.render_buffers.is_valid() && p_use_gi; + + if (render_shadows && render_gi) { + RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)"); + } else if (render_shadows) { + RENDER_TIMESTAMP("Render Shadows"); + } else if (render_gi) { + RENDER_TIMESTAMP("Render GI"); } - current_cluster_builder->begin(p_cam_transform, p_cam_projection, !p_reflection_probe.is_valid()); + //prepare shadow rendering + if (render_shadows) { + _render_shadow_begin(); + + //render directional shadows + for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) { + _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false); + } + //render positional shadows + for (uint32_t i = 0; i < render_state.shadows.size(); i++) { + _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true); + } + + _render_shadow_process(); + } + + //start GI + if (render_gi) { + _process_gi(render_state.render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, render_state.environment, render_state.cam_projection, render_state.cam_transform, *render_state.gi_probes); + } + + //Do shadow rendering (in parallel with GI) + if (render_shadows) { + _render_shadow_end(RD::BARRIER_MASK_NO_BARRIER); + } + + if (render_gi) { + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier + } + + if (render_state.render_buffers.is_valid()) { + if (p_use_ssao) { + _process_ssao(render_state.render_buffers, render_state.environment, p_normal_roughness_buffer, render_state.cam_projection); + } + } + + //full barrier here, we need raster, transfer and compute and it depends from the previous work + RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); + + if (current_cluster_builder) { + current_cluster_builder->begin(render_state.cam_transform, render_state.cam_projection, !render_state.reflection_probe.is_valid()); + } bool using_shadows = true; - if (p_reflection_probe.is_valid()) { - if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_reflection_probe))) { + if (render_state.reflection_probe.is_valid()) { + if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(render_state.reflection_probe))) { using_shadows = false; } } else { //do not render reflections when rendering a reflection probe - _setup_reflections(*reflections, p_cam_transform.affine_inverse(), p_environment); + _setup_reflections(*render_state.reflection_probes, render_state.cam_transform.affine_inverse(), render_state.environment); } uint32_t directional_light_count = 0; uint32_t positional_light_count = 0; - _setup_lights(*lights, p_cam_transform, p_shadow_atlas, using_shadows, directional_light_count, positional_light_count); - _setup_decals(p_decals, p_cam_transform.affine_inverse()); + _setup_lights(*render_state.lights, render_state.cam_transform, render_state.shadow_atlas, using_shadows, directional_light_count, positional_light_count); + _setup_decals(*render_state.decals, render_state.cam_transform.affine_inverse()); - current_cluster_builder->bake_cluster(); + render_state.directional_light_count = directional_light_count; - uint32_t gi_probe_count = 0; - if (p_render_buffers.is_valid()) { - _setup_giprobes(p_render_buffers, p_cam_transform, *gi_probes, gi_probe_count); + if (current_cluster_builder) { + current_cluster_builder->bake_cluster(); } - if (p_render_buffers.is_valid()) { + if (render_state.render_buffers.is_valid()) { bool directional_shadows = false; for (uint32_t i = 0; i < directional_light_count; i++) { if (cluster.directional_lights[i].shadow_enabled) { @@ -7409,10 +7363,103 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & break; } } - _update_volumetric_fog(p_render_buffers, p_environment, p_cam_projection, p_cam_transform, p_shadow_atlas, directional_light_count, directional_shadows, positional_light_count, gi_probe_count); + _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count); } +} - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, directional_light_count, *gi_probes, p_lightmaps, p_environment, current_cluster_builder->get_cluster_buffer(), current_cluster_builder->get_cluster_size(), current_cluster_builder->get_max_cluster_elements(), p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold); +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data) { + //assign render data + { + render_state.render_buffers = p_render_buffers; + render_state.cam_transform = p_cam_transform; + render_state.cam_projection = p_cam_projection; + render_state.cam_ortogonal = p_cam_projection.is_orthogonal(); + render_state.instances = &p_instances; + render_state.lights = &p_lights; + render_state.reflection_probes = &p_reflection_probes; + render_state.gi_probes = &p_gi_probes; + render_state.decals = &p_decals; + render_state.lightmaps = &p_lightmaps; + render_state.environment = p_environment; + render_state.camera_effects = p_camera_effects; + render_state.shadow_atlas = p_shadow_atlas; + render_state.reflection_atlas = p_reflection_atlas; + render_state.reflection_probe = p_reflection_probe; + render_state.reflection_probe_pass = p_reflection_probe_pass; + render_state.screen_lod_threshold = p_screen_lod_threshold; + + render_state.render_shadows = p_render_shadows; + render_state.render_shadow_count = p_render_shadow_count; + render_state.render_sdfgi_regions = p_render_sdfgi_regions; + render_state.render_sdfgi_region_count = p_render_sdfgi_region_count; + render_state.sdfgi_update_data = p_sdfgi_update_data; + } + + PagedArray<RID> empty; + + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { + render_state.lights = ∅ + render_state.reflection_probes = ∅ + render_state.gi_probes = ∅ + } + + //sdfgi first + if (p_render_buffers.is_valid()) { + for (int i = 0; i < render_state.render_sdfgi_region_count; i++) { + _render_sdfgi_region(p_render_buffers, render_state.render_sdfgi_regions[i].region, render_state.render_sdfgi_regions[i].instances); + } + if (render_state.sdfgi_update_data->update_static) { + _render_sdfgi_static_lights(p_render_buffers, render_state.sdfgi_update_data->static_cascade_count, p_sdfgi_update_data->static_cascade_indices, render_state.sdfgi_update_data->static_positional_lights); + } + } + + Color clear_color; + if (p_render_buffers.is_valid()) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + ERR_FAIL_COND(!rb); + clear_color = storage->render_target_get_clear_request_color(rb->render_target); + } else { + clear_color = storage->get_default_clear_color(); + } + + //assign render indices to giprobes + for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) { + GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]); + if (giprobe_inst) { + giprobe_inst->render_index = i; + } + } + + if (render_buffers_owner.owns(render_state.render_buffers)) { + RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); + current_cluster_builder = rb->cluster_builder; + } else if (reflection_probe_instance_owner.owns(render_state.reflection_probe)) { + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_state.reflection_probe); + ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas); + if (!ra) { + ERR_PRINT("reflection probe has no reflection atlas! Bug?"); + current_cluster_builder = nullptr; + } else { + current_cluster_builder = ra->cluster_builder; + } + } else { + ERR_PRINT("No cluster builder, bug"); //should never happen, will crash + current_cluster_builder = nullptr; + } + + if (p_render_buffers.is_valid()) { + _pre_process_gi(p_render_buffers, p_cam_transform); + } + + render_state.gi_probe_count = 0; + if (render_state.render_buffers.is_valid()) { + _setup_giprobes(render_state.render_buffers, render_state.cam_transform, *render_state.gi_probes, render_state.gi_probe_count); + _sdfgi_update_light(render_state.render_buffers, render_state.environment); + } + + render_state.depth_prepass_used = false; + //calls _pre_opaque_render between depth pre-pass and opaque pass + _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, current_cluster_builder->get_cluster_buffer(), current_cluster_builder->get_cluster_size(), current_cluster_builder->get_max_cluster_elements(), p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold); if (p_render_buffers.is_valid()) { if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES) { @@ -7446,7 +7493,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & } } -void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region) { LightInstance *light_instance = light_instance_owner.getornull(p_light); ERR_FAIL_COND(!light_instance); @@ -7469,13 +7516,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p CameraMatrix light_projection; Transform light_transform; - bool clear_region = true; - bool begin_texture = true; - bool end_texture = true; - if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) { - _update_directional_shadow_atlas(); - //set pssm stuff if (light_instance->last_scene_shadow_pass != scene_pass) { light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light); @@ -7492,7 +7533,6 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.size.width = light_instance->directional_rect.size.x; atlas_rect.size.height = light_instance->directional_rect.size.y; - int pass_count = 1; if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { atlas_rect.size.width /= 2; atlas_rect.size.height /= 2; @@ -7505,7 +7545,6 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.position.x += atlas_rect.size.width; atlas_rect.position.y += atlas_rect.size.height; } - pass_count = 4; } else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { atlas_rect.size.height /= 2; @@ -7513,7 +7552,6 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p } else { atlas_rect.position.y += atlas_rect.size.height; } - pass_count = 2; } light_instance->shadow_transform[p_pass].atlas_rect = atlas_rect; @@ -7527,10 +7565,6 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p render_texture = RID(); flip_y = true; - clear_region = false; - begin_texture = (directional_shadow.current_light == 1) && (p_pass == 0); //light is 1-index because it was incremented above - end_texture = (directional_shadow.current_light == directional_shadow.light_count) && (p_pass == pass_count - 1); - } else { //set from shadow atlas @@ -7568,14 +7602,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p render_fb = cubemap->side_fb[p_pass]; render_texture = cubemap->cubemap; - light_projection = light_instance->shadow_transform[0].camera; - light_transform = light_instance->shadow_transform[0].transform; + light_projection = light_instance->shadow_transform[p_pass].camera; + light_transform = light_instance->shadow_transform[p_pass].transform; render_cubemap = true; finalize_cubemap = p_pass == 5; atlas_fb = shadow_atlas->fb; atlas_size = shadow_atlas->size; - clear_region = false; + + if (p_pass == 0) { + _render_shadow_begin(); + } } else { light_projection = light_instance->shadow_transform[0].camera; @@ -7602,8 +7639,10 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p if (render_cubemap) { //rendering to cubemap - _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true); if (finalize_cubemap) { + _render_shadow_process(); + _render_shadow_end(); //reblit Rect2 atlas_rect_norm = atlas_rect; atlas_rect_norm.position.x /= float(atlas_size); @@ -7614,10 +7653,14 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false); atlas_rect_norm.position.y += atlas_rect_norm.size.height; storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true); + + //restore transform so it can be properly used + light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0); } + } else { //render shadow - _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, clear_region, begin_texture, end_texture); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass); } } @@ -7625,7 +7668,7 @@ void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, co _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region); } -void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) { +void RendererSceneRenderRD::_render_sdfgi_region(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) { //print_line("rendering region " + itos(p_region)); RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -7651,6 +7694,8 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con _render_sdfgi(p_render_buffers, from, size, bounds, p_instances, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing); if (cascade_next != cascade) { + RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade"); + RENDER_TIMESTAMP(">SDFGI Update SDF"); //done rendering! must update SDF //clear dispatch indirect data @@ -7700,7 +7745,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con groups.z = rb->sdfgi->cascade_size - ABS(dirty.z); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z); //no barrier, continue together @@ -7742,7 +7787,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -7750,11 +7795,11 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1); RD::get_singleton()->compute_list_add_barrier(compute_list); - if (rb->sdfgi->uses_multibounce) { + if (rb->sdfgi->bounce_feedback > 0.0) { //multibounce requires this to be stored so direct light can read from it RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]); @@ -7766,7 +7811,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1); } } @@ -7790,7 +7835,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_initialize_half_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); RD::get_singleton()->compute_list_add_barrier(compute_list); //must start with regular jumpflood @@ -7810,7 +7855,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_half_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; @@ -7828,7 +7873,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_half_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; } @@ -7840,7 +7885,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_upscale_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); //run one pass of fullsize jumpflood to fix up half size arctifacts @@ -7850,7 +7895,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[rb->sdfgi->upscale_jfa_uniform_set_index], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); } else { @@ -7860,7 +7905,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_initialize_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -7877,7 +7922,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; @@ -7895,7 +7940,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con push_constant.step_size = s; RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[jf_us], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_add_barrier(compute_list); jf_us = jf_us == 0 ? 1 : 0; } @@ -7942,7 +7987,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_STORE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].sdf_store_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size); RD::get_singleton()->compute_list_end(); @@ -7979,6 +8024,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con #endif RENDER_TIMESTAMP("<SDFGI Update SDF"); + RD::get_singleton()->draw_command_end_label(); } } @@ -7999,11 +8045,13 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, _render_particle_collider_heightfield(fb, cam_xform, cm, p_instances); } -void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) { +void RendererSceneRenderRD::_render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); ERR_FAIL_COND(!rb->sdfgi); + RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs"); + _sdfgi_update_cascades(p_render_buffers); //need cascades updated for this SDGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS]; @@ -8063,8 +8111,8 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin lights[idx].has_shadow = storage->light_has_shadow(li->light); lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION); lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE); - lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)); - lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); + lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE))); + lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION); idx++; } @@ -8089,8 +8137,9 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size; dl_push_constant.max_cascades = rb->sdfgi->cascades.size(); dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count; - dl_push_constant.multibounce = false; // this is static light, do not multibounce yet + dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet dl_push_constant.y_mult = rb->sdfgi->y_mult; + dl_push_constant.use_occlusion = rb->sdfgi->uses_occlusion; //all must be processed dl_push_constant.process_offset = 0; @@ -8112,6 +8161,8 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin } RD::get_singleton()->compute_list_end(); + + RD::get_singleton()->draw_command_end_label(); } bool RendererSceneRenderRD::free(RID p_rid) { @@ -8547,9 +8598,14 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { { // default material and shader for sky shader - sky_shader.default_shader = storage->shader_create(); + sky_shader.default_shader = storage->shader_allocate(); + storage->shader_initialize(sky_shader.default_shader); + storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n"); - sky_shader.default_material = storage->material_create(); + + sky_shader.default_material = storage->material_allocate(); + storage->material_initialize(sky_shader.default_material); + storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader); SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY); @@ -8623,9 +8679,13 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { { // Need defaults for using fog with clear color - sky_scene_state.fog_shader = storage->shader_create(); + sky_scene_state.fog_shader = storage->shader_allocate(); + storage->shader_initialize(sky_scene_state.fog_shader); + storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void fragment() { COLOR = clear_color.rgb; } \n"); - sky_scene_state.fog_material = storage->material_create(); + sky_scene_state.fog_material = storage->material_allocate(); + storage->material_initialize(sky_scene_state.fog_material); + storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader); Vector<RD::Uniform> uniforms; @@ -8785,11 +8845,19 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES); } + { //decals + cluster.max_decals = max_cluster_elements; + uint32_t decal_buffer_size = cluster.max_decals * sizeof(Cluster::DecalData); + cluster.decals = memnew_arr(Cluster::DecalData, cluster.max_decals); + cluster.decal_sort = memnew_arr(Cluster::InstanceSort<DecalInstance>, cluster.max_decals); + cluster.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); + } + { //reflections cluster.max_reflections = max_cluster_elements; cluster.reflections = memnew_arr(Cluster::ReflectionData, cluster.max_reflections); - cluster.reflection_sort = memnew_arr(Cluster::InstanceSort<ReflectionProbeInstance>, cluster.max_decals); + cluster.reflection_sort = memnew_arr(Cluster::InstanceSort<ReflectionProbeInstance>, cluster.max_reflections); cluster.reflection_buffer = RD::get_singleton()->storage_buffer_create(sizeof(Cluster::ReflectionData) * cluster.max_reflections); } @@ -8805,24 +8873,12 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { cluster.spot_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights); //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n"; - //used for volumetric fog shrinking - cluster.lights_instances = memnew_arr(RID, cluster.max_lights * 2); - cluster.lights_shadow_rect_cache = memnew_arr(Rect2i, cluster.max_lights * 2); - cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS; uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData); cluster.directional_lights = memnew_arr(Cluster::DirectionalLightData, cluster.max_directional_lights); cluster.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size); } - { //decals - cluster.max_decals = max_cluster_elements; - uint32_t decal_buffer_size = cluster.max_decals * sizeof(Cluster::DecalData); - cluster.decals = memnew_arr(Cluster::DecalData, cluster.max_decals); - cluster.decal_sort = memnew_arr(Cluster::InstanceSort<DecalInstance>, cluster.max_decals); - cluster.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); - } - if (!low_end) { String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n"; Vector<String> volumetric_fog_modes; @@ -8868,8 +8924,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth")); environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter")); - environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink")); - environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); cull_argument.set_page_pool(&cull_argument_pool); @@ -8931,8 +8985,6 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { memdelete_arr(cluster.spot_lights); memdelete_arr(cluster.omni_light_sort); memdelete_arr(cluster.spot_light_sort); - memdelete_arr(cluster.lights_shadow_rect_cache); - memdelete_arr(cluster.lights_instances); memdelete_arr(cluster.reflections); memdelete_arr(cluster.reflection_sort); memdelete_arr(cluster.decals); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index af8cdb9b71..e4eaa93212 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -109,8 +109,13 @@ protected: void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment); void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used); - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0; - virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0; + + virtual void _render_shadow_begin() = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; + virtual void _render_shadow_process() = 0; + virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; + virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; @@ -132,8 +137,16 @@ protected: void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size); void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform); + void _pre_process_gi(RID p_render_buffers, const Transform &p_transform); void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes); + bool _needs_post_prepass_render(bool p_use_gi); + void _post_prepass_render(bool p_use_gi); + void _pre_resolve_render(bool p_use_gi); + + void _pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer); + uint32_t _get_render_state_directional_light_count() const; + // needed for a single argument calls (material and uv2) PagedArrayPool<GeometryInstance *> cull_argument_pool; PagedArray<GeometryInstance *> cull_argument; //need this to exist @@ -320,7 +333,7 @@ private: uint32_t sky_ggx_samples_quality; bool sky_use_cubemap_array; - mutable RID_Owner<Sky> sky_owner; + mutable RID_Owner<Sky, true> sky_owner; /* REFLECTION ATLAS */ @@ -393,10 +406,10 @@ private: float attenuation; float color[3]; - float spot_angle_radians; + float cos_spot_angle; float position[3]; - float spot_attenuation; + float inv_spot_attenuation; float direction[3]; uint32_t has_shadow; @@ -578,8 +591,6 @@ private: RID fb; //for copying Map<RID, uint32_t> shadow_owners; - - Vector<ShadowShrinkStage> shrink_stages; }; RID_Owner<ShadowAtlas> shadow_atlas_owner; @@ -613,13 +624,8 @@ private: bool use_16_bits = false; int current_light = 0; - Vector<ShadowShrinkStage> shrink_stages; - } directional_shadow; - void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size); - void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages); - void _update_directional_shadow_atlas(); /* SHADOW CUBEMAPS */ @@ -651,7 +657,7 @@ private: RS::LightType light_type = RS::LIGHT_DIRECTIONAL; - ShadowTransform shadow_transform[4]; + ShadowTransform shadow_transform[6]; AABB aabb; RID self; @@ -730,8 +736,9 @@ private: float volumetric_fog_light_energy = 0.0; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - RS::EnvVolumetricFogShadowFilter volumetric_fog_shadow_filter = RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW; float volumetric_fog_gi_inject = 0.0; + bool volumetric_fog_temporal_reprojection = true; + float volumetric_fog_temporal_reprojection_amount = 0.9; /// Glow @@ -771,7 +778,7 @@ private: RS::EnvironmentSDFGICascades sdfgi_cascades; float sdfgi_min_cell_size = 0.2; bool sdfgi_use_occlusion = false; - bool sdfgi_use_multibounce = false; + float sdfgi_bounce_feedback = 0.0; bool sdfgi_read_sky_light = false; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; @@ -802,7 +809,7 @@ private: static uint64_t auto_exposure_counter; - mutable RID_Owner<Environment> environment_owner; + mutable RID_Owner<Environment, true> environment_owner; /* CAMERA EFFECTS */ @@ -828,7 +835,7 @@ private: float sss_scale = 0.05; float sss_depth_scale = 0.01; - mutable RID_Owner<CameraEffects> camera_effects_owner; + mutable RID_Owner<CameraEffects, true> camera_effects_owner; /* RENDER BUFFERS */ @@ -1021,7 +1028,7 @@ private: RID cascades_ubo; bool uses_occlusion = false; - bool uses_multibounce = false; + float bounce_feedback = 0.0; bool reads_sky = false; float energy = 1.0; float normal_bias = 1.1; @@ -1031,8 +1038,14 @@ private: float y_mult = 1.0; uint32_t render_pass = 0; + + int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically }; + void _sdfgi_update_light(RID p_render_buffers, RID p_environment); + void _sdfgi_update_probes(RID p_render_buffers, RID p_environment); + void _sdfgi_store_probes(RID p_render_buffers); + RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16; RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_10_FRAMES; RS::EnvironmentSDFGIFramesToUpdateLight sdfgi_frames_to_update_light = RS::ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES; @@ -1133,8 +1146,8 @@ private: float attenuation; uint32_t type; - float spot_angle; - float spot_attenuation; + float cos_spot_angle; + float inv_spot_attenuation; float radius; float shadow_color[4]; @@ -1150,9 +1163,9 @@ private: uint32_t process_increment; int32_t probe_axis_size; - uint32_t multibounce; + float bounce_feedback; float y_mult; - uint32_t pad; + uint32_t use_occlusion; }; enum { @@ -1349,8 +1362,8 @@ private: float color[3]; float attenuation; - float cone_attenuation; - float cone_angle; + float inv_spot_attenuation; + float cos_spot_angle; float specular_amount; uint32_t shadow_enabled; @@ -1450,17 +1463,52 @@ private: uint32_t omni_light_count = 0; uint32_t spot_light_count = 0; - RID *lights_instances; - Rect2i *lights_shadow_rect_cache; - uint32_t lights_shadow_rect_cache_count = 0; - DirectionalLightData *directional_lights; uint32_t max_directional_lights; RID directional_light_buffer; } cluster; + struct RenderState { + RID render_buffers; + Transform cam_transform; + CameraMatrix cam_projection; + bool cam_ortogonal = false; + const PagedArray<GeometryInstance *> *instances = nullptr; + const PagedArray<RID> *lights = nullptr; + const PagedArray<RID> *reflection_probes = nullptr; + const PagedArray<RID> *gi_probes = nullptr; + const PagedArray<RID> *decals = nullptr; + const PagedArray<RID> *lightmaps = nullptr; + RID environment; + RID camera_effects; + RID shadow_atlas; + RID reflection_atlas; + RID reflection_probe; + int reflection_probe_pass = 0; + float screen_lod_threshold = 0.0; + + const RenderShadowData *render_shadows = nullptr; + int render_shadow_count = 0; + const RenderSDFGIData *render_sdfgi_regions = nullptr; + int render_sdfgi_region_count = 0; + const RenderSDFGIUpdateData *sdfgi_update_data = nullptr; + + uint32_t directional_light_count = 0; + uint32_t gi_probe_count = 0; + + LocalVector<int> cube_shadows; + LocalVector<int> shadows; + LocalVector<int> directional_shadows; + + bool depth_prepass_used; + } render_state; + struct VolumetricFog { + enum { + MAX_TEMPORAL_FRAMES = 16 + }; + uint32_t width = 0; uint32_t height = 0; uint32_t depth = 0; @@ -1469,6 +1517,8 @@ private: float spread; RID light_density_map; + RID prev_light_density_map; + RID fog_map; RID uniform_set; RID uniform_set2; @@ -1476,6 +1526,8 @@ private: RID sky_uniform_set; int last_shadow_filter = -1; + + Transform prev_cam_transform; }; enum { @@ -1511,10 +1563,13 @@ private: uint32_t cluster_shift; uint32_t cluster_width; - uint32_t cluster_pad[3]; uint32_t max_cluster_element_count_div_32; + uint32_t use_temporal_reprojection; + uint32_t temporal_frame; + float temporal_blend; float cam_rotation[12]; + float to_prev_view[16]; }; VolumetricFogShaderRD shader; @@ -1527,9 +1582,7 @@ private: uint32_t volumetric_fog_depth = 128; uint32_t volumetric_fog_size = 128; - bool volumetric_fog_filter_active = false; - uint32_t volumetric_fog_directional_shadow_shrink = 512; - uint32_t volumetric_fog_positional_shadow_shrink = 512; + bool volumetric_fog_filter_active = true; void _volumetric_fog_erase(RenderBuffers *rb); void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count); @@ -1547,6 +1600,10 @@ private: uint32_t max_cluster_elements = 512; bool low_end = false; + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true); + void _render_sdfgi_region(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances); + void _render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result); + public: virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0; virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; @@ -1594,11 +1651,12 @@ public: virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const; virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const; virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const; - virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count); RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; } /* SKY API */ - RID sky_create(); + virtual RID sky_allocate(); + virtual void sky_initialize(RID p_rid); + void sky_set_radiance_size(RID p_sky, int p_radiance_size); void sky_set_mode(RID p_sky, RS::SkyMode p_mode); void sky_set_material(RID p_sky, RID p_material); @@ -1610,7 +1668,8 @@ public: /* ENVIRONMENT API */ - RID environment_create(); + virtual RID environment_allocate(); + virtual void environment_initialize(RID p_rid); void environment_set_background(RID p_env, RS::EnvironmentBG p_bg); void environment_set_sky(RID p_env, RID p_sky); @@ -1651,12 +1710,10 @@ public: float environment_get_fog_height_density(RID p_env) const; float environment_get_fog_aerial_perspective(RID p_env) const; - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter); + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount); virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth); virtual void environment_set_volumetric_fog_filter_active(bool p_enable); - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size); - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size); void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect); @@ -1667,7 +1724,7 @@ public: bool environment_is_ssr_enabled(RID p_env) const; bool environment_is_sdfgi_enabled(RID p_env) const; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias); virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count); virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames); virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update); @@ -1680,7 +1737,8 @@ public: virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size); - virtual RID camera_effects_create(); + virtual RID camera_effects_allocate(); + virtual void camera_effects_initialize(RID p_rid); virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter); virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape); @@ -1997,15 +2055,10 @@ public: float render_buffers_get_volumetric_fog_end(RID p_render_buffers); float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers); - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold); - - void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0); + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr); void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region); - void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances); - void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result); - void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances); virtual void set_scene_pass(uint64_t p_pass) { diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 6d4343e183..f25cd2ade4 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -36,6 +36,10 @@ #include "renderer_compositor_rd.h" #include "servers/rendering/shader_language.h" +bool RendererStorageRD::can_create_resources_async() const { + return true; +} + Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { Ref<Image> image = p_image->duplicate(); @@ -535,9 +539,13 @@ Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image return image; } -RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { - ERR_FAIL_COND_V(p_image.is_null(), RID()); - ERR_FAIL_COND_V(p_image->is_empty(), RID()); +RID RendererStorageRD::texture_allocate() { + return texture_owner.allocate_rid(); +} + +void RendererStorageRD::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) { + ERR_FAIL_COND(p_image.is_null()); + ERR_FAIL_COND(p_image->is_empty()); TextureToRDFormat ret_format; Ref<Image> image = _validate_texture_format(p_image, ret_format); @@ -585,13 +593,13 @@ RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { Vector<Vector<uint8_t>> data_slices; data_slices.push_back(data); texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture.is_null()); if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { rd_view.format_override = texture.rd_format_srgb; texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); if (texture.rd_texture_srgb.is_null()) { RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); } } @@ -602,14 +610,14 @@ RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) { texture.rd_view = rd_view; texture.is_proxy = false; - return texture_owner.make_rid(texture); + texture_owner.initialize_rid(p_texture, texture); } -RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { - ERR_FAIL_COND_V(p_layers.size() == 0, RID()); +void RendererStorageRD::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { + ERR_FAIL_COND(p_layers.size() == 0); - ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID()); - ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0), RID()); + ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6); + ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0)); TextureToRDFormat ret_format; Vector<Ref<Image>> images; @@ -620,7 +628,7 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay Image::Format valid_format = Image::FORMAT_MAX; for (int i = 0; i < p_layers.size(); i++) { - ERR_FAIL_COND_V(p_layers[i]->is_empty(), RID()); + ERR_FAIL_COND(p_layers[i]->is_empty()); if (i == 0) { valid_width = p_layers[i]->get_width(); @@ -628,10 +636,10 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay valid_format = p_layers[i]->get_format(); valid_mipmaps = p_layers[i]->has_mipmaps(); } else { - ERR_FAIL_COND_V(p_layers[i]->get_width() != valid_width, RID()); - ERR_FAIL_COND_V(p_layers[i]->get_height() != valid_height, RID()); - ERR_FAIL_COND_V(p_layers[i]->get_format() != valid_format, RID()); - ERR_FAIL_COND_V(p_layers[i]->has_mipmaps() != valid_mipmaps, RID()); + ERR_FAIL_COND(p_layers[i]->get_width() != valid_width); + ERR_FAIL_COND(p_layers[i]->get_height() != valid_height); + ERR_FAIL_COND(p_layers[i]->get_format() != valid_format); + ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps); } images.push_back(_validate_texture_format(p_layers[i], ret_format)); @@ -695,13 +703,13 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay data_slices.push_back(data); } texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture.is_null()); if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { rd_view.format_override = texture.rd_format_srgb; texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); if (texture.rd_texture_srgb.is_null()) { RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); } } @@ -712,14 +720,14 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay texture.rd_view = rd_view; texture.is_proxy = false; - return texture_owner.make_rid(texture); + texture_owner.initialize_rid(p_texture, texture); } -RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { - ERR_FAIL_COND_V(p_data.size() == 0, RID()); +void RendererStorageRD::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { + ERR_FAIL_COND(p_data.size() == 0); Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); if (verr != Image::VALIDATE_3D_OK) { - ERR_FAIL_V_MSG(RID(), Image::get_3d_image_validation_error_text(verr)); + ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); } TextureToRDFormat ret_format; @@ -811,13 +819,13 @@ RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, in data_slices.push_back(all_data); //one slice texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture.is_null()); if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { rd_view.format_override = texture.rd_format_srgb; texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); if (texture.rd_texture_srgb.is_null()) { RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); } } @@ -828,12 +836,12 @@ RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, in texture.rd_view = rd_view; texture.is_proxy = false; - return texture_owner.make_rid(texture); + texture_owner.initialize_rid(p_texture, texture); } -RID RendererStorageRD::texture_proxy_create(RID p_base) { +void RendererStorageRD::texture_proxy_initialize(RID p_texture, RID p_base) { Texture *tex = texture_owner.getornull(p_base); - ERR_FAIL_COND_V(!tex, RID()); + ERR_FAIL_COND(!tex); Texture proxy_tex = *tex; proxy_tex.rd_view.format_override = tex->rd_format; @@ -847,11 +855,9 @@ RID RendererStorageRD::texture_proxy_create(RID p_base) { proxy_tex.is_proxy = true; proxy_tex.proxies.clear(); - RID rid = texture_owner.make_rid(proxy_tex); - - tex->proxies.push_back(rid); + texture_owner.initialize_rid(p_texture, proxy_tex); - return rid; + tex->proxies.push_back(p_texture); } void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { @@ -961,7 +967,7 @@ void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { } //these two APIs can be used together or in combination with the others. -RID RendererStorageRD::texture_2d_placeholder_create() { +void RendererStorageRD::texture_2d_placeholder_initialize(RID p_texture) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -974,10 +980,10 @@ RID RendererStorageRD::texture_2d_placeholder_create() { } } - return texture_2d_create(image); + texture_2d_initialize(p_texture, image); } -RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) { +void RendererStorageRD::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -1000,10 +1006,10 @@ RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredT } } - return texture_2d_layered_create(images, p_layered_type); + texture_2d_layered_initialize(p_texture, images, p_layered_type); } -RID RendererStorageRD::texture_3d_placeholder_create() { +void RendererStorageRD::texture_3d_placeholder_initialize(RID p_texture) { //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -1022,7 +1028,7 @@ RID RendererStorageRD::texture_3d_placeholder_create() { images.push_back(image); } - return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images); + texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images); } Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const { @@ -1223,8 +1229,11 @@ RendererStorageRD::CanvasTexture::~CanvasTexture() { clear_sets(); } -RID RendererStorageRD::canvas_texture_create() { - return canvas_texture_owner.make_rid(memnew(CanvasTexture)); +RID RendererStorageRD::canvas_texture_allocate() { + return canvas_texture_owner.allocate_rid(); +} +void RendererStorageRD::canvas_texture_initialize(RID p_rid) { + canvas_texture_owner.initialize_rid(p_rid, memnew(CanvasTexture)); } void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { @@ -1365,12 +1374,15 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas /* SHADER API */ -RID RendererStorageRD::shader_create() { +RID RendererStorageRD::shader_allocate() { + return shader_owner.allocate_rid(); +} +void RendererStorageRD::shader_initialize(RID p_rid) { Shader shader; shader.data = nullptr; shader.type = SHADER_TYPE_MAX; - return shader_owner.make_rid(shader); + shader_owner.initialize_rid(p_rid, shader); } void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { @@ -1510,7 +1522,10 @@ RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID /* COMMON MATERIAL API */ -RID RendererStorageRD::material_create() { +RID RendererStorageRD::material_allocate() { + return material_owner.allocate_rid(); +} +void RendererStorageRD::material_initialize(RID p_rid) { Material material; material.data = nullptr; material.shader = nullptr; @@ -1520,12 +1535,8 @@ RID RendererStorageRD::material_create() { material.uniform_dirty = false; material.texture_dirty = false; material.priority = 0; - RID id = material_owner.make_rid(material); - { - Material *material_ptr = material_owner.getornull(id); - material_ptr->self = id; - } - return id; + material.self = p_rid; + material_owner.initialize_rid(p_rid, material); } void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) { @@ -2399,8 +2410,11 @@ void RendererStorageRD::_update_queued_materials() { /* MESH API */ -RID RendererStorageRD::mesh_create() { - return mesh_owner.make_rid(Mesh()); +RID RendererStorageRD::mesh_allocate() { + return mesh_owner.allocate_rid(); +} +void RendererStorageRD::mesh_initialize(RID p_rid) { + mesh_owner.initialize_rid(p_rid, Mesh()); } void RendererStorageRD::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) { @@ -3098,7 +3112,7 @@ void RendererStorageRD::update_mesh_instances() { RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SkeletonShader::PushConstant)); //dispatch without barrier, so all is done at the same time - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1); } mi->dirty = false; @@ -3298,11 +3312,14 @@ void RendererStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surf ////////////////// MULTIMESH -RID RendererStorageRD::multimesh_create() { - return multimesh_owner.make_rid(MultiMesh()); +RID RendererStorageRD::multimesh_allocate() { + return multimesh_owner.allocate_rid(); +} +void RendererStorageRD::multimesh_initialize(RID p_rid) { + multimesh_owner.initialize_rid(p_rid, MultiMesh()); } -void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { +void RendererStorageRD::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -3849,8 +3866,11 @@ void RendererStorageRD::_update_dirty_multimeshes() { /* PARTICLES */ -RID RendererStorageRD::particles_create() { - return particles_owner.make_rid(Particles()); +RID RendererStorageRD::particles_allocate() { + return particles_owner.allocate_rid(); +} +void RendererStorageRD::particles_initialize(RID p_rid) { + particles_owner.initialize_rid(p_rid, Particles()); } void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) { @@ -4555,7 +4575,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); } @@ -4609,7 +4629,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); @@ -4621,7 +4641,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); } @@ -4728,7 +4748,7 @@ void RendererStorageRD::update_particles() { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1); RD::get_singleton()->compute_list_end(); } @@ -4984,8 +5004,11 @@ RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_f /* PARTICLES COLLISION API */ -RID RendererStorageRD::particles_collision_create() { - return particles_collision_owner.make_rid(ParticlesCollision()); +RID RendererStorageRD::particles_collision_allocate() { + return particles_collision_owner.allocate_rid(); +} +void RendererStorageRD::particles_collision_initialize(RID p_rid) { + particles_collision_owner.initialize_rid(p_rid, ParticlesCollision()); } RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { @@ -5164,8 +5187,11 @@ void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_ /* SKELETON API */ -RID RendererStorageRD::skeleton_create() { - return skeleton_owner.make_rid(Skeleton()); +RID RendererStorageRD::skeleton_allocate() { + return skeleton_owner.allocate_rid(); +} +void RendererStorageRD::skeleton_initialize(RID p_rid) { + skeleton_owner.initialize_rid(p_rid, Skeleton()); } void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { @@ -5176,7 +5202,7 @@ void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { } } -void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { +void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_COND(p_bones < 0); @@ -5350,7 +5376,7 @@ void RendererStorageRD::_update_dirty_skeletons() { /* LIGHT */ -RID RendererStorageRD::light_create(RS::LightType p_type) { +void RendererStorageRD::_light_initialize(RID p_light, RS::LightType p_type) { Light light; light.type = p_type; @@ -5371,10 +5397,31 @@ RID RendererStorageRD::light_create(RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0; + light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; - return light_owner.make_rid(light); + light_owner.initialize_rid(p_light, light); +} + +RID RendererStorageRD::directional_light_allocate() { + return light_owner.allocate_rid(); +} +void RendererStorageRD::directional_light_initialize(RID p_light) { + _light_initialize(p_light, RS::LIGHT_DIRECTIONAL); +} + +RID RendererStorageRD::omni_light_allocate() { + return light_owner.allocate_rid(); +} +void RendererStorageRD::omni_light_initialize(RID p_light) { + _light_initialize(p_light, RS::LIGHT_OMNI); +} + +RID RendererStorageRD::spot_light_allocate() { + return light_owner.allocate_rid(); +} +void RendererStorageRD::spot_light_initialize(RID p_light) { + _light_initialize(p_light, RS::LIGHT_SPOT); } void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) { @@ -5612,8 +5659,11 @@ AABB RendererStorageRD::light_get_aabb(RID p_light) const { /* REFLECTION PROBE */ -RID RendererStorageRD::reflection_probe_create() { - return reflection_probe_owner.make_rid(ReflectionProbe()); +RID RendererStorageRD::reflection_probe_allocate() { + return reflection_probe_owner.allocate_rid(); +} +void RendererStorageRD::reflection_probe_initialize(RID p_reflection_probe) { + reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe()); } void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { @@ -5835,8 +5885,11 @@ float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) return reflection_probe->ambient_color_energy; } -RID RendererStorageRD::decal_create() { - return decal_owner.make_rid(Decal()); +RID RendererStorageRD::decal_allocate() { + return decal_owner.allocate_rid(); +} +void RendererStorageRD::decal_initialize(RID p_decal) { + decal_owner.initialize_rid(p_decal, Decal()); } void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) { @@ -5923,11 +5976,14 @@ AABB RendererStorageRD::decal_get_aabb(RID p_decal) const { return AABB(-decal->extents, decal->extents * 2.0); } -RID RendererStorageRD::gi_probe_create() { - return gi_probe_owner.make_rid(GIProbe()); +RID RendererStorageRD::gi_probe_allocate() { + return gi_probe_owner.allocate_rid(); +} +void RendererStorageRD::gi_probe_initialize(RID p_gi_probe) { + gi_probe_owner.initialize_rid(p_gi_probe, GIProbe()); } -void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { +void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -6276,8 +6332,12 @@ RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { /* LIGHTMAP API */ -RID RendererStorageRD::lightmap_create() { - return lightmap_owner.make_rid(Lightmap()); +RID RendererStorageRD::lightmap_allocate() { + return lightmap_owner.allocate_rid(); +} + +void RendererStorageRD::lightmap_initialize(RID p_lightmap) { + lightmap_owner.initialize_rid(p_lightmap, Lightmap()); } void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { @@ -6480,7 +6540,8 @@ void RendererStorageRD::_clear_render_target(RenderTarget *rt) { void RendererStorageRD::_update_render_target(RenderTarget *rt) { if (rt->texture.is_null()) { //create a placeholder until updated - rt->texture = texture_2d_placeholder_create(); + rt->texture = texture_allocate(); + texture_2d_placeholder_initialize(rt->texture); Texture *tex = texture_owner.getornull(rt->texture); tex->is_render_target = true; } @@ -6980,7 +7041,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0] RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1); /* Process */ @@ -6996,7 +7057,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0); push_constant.stride = stride; RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1); stride /= 2; swap = !swap; RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -7007,7 +7068,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1); RD::get_singleton()->compute_list_end(); } @@ -8217,13 +8278,13 @@ bool RendererStorageRD::free(RID p_rid) { } else if (multimesh_owner.owns(p_rid)) { _update_dirty_multimeshes(); - multimesh_allocate(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D); + multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D); MultiMesh *multimesh = multimesh_owner.getornull(p_rid); multimesh->dependency.deleted_notify(p_rid); multimesh_owner.free(p_rid); } else if (skeleton_owner.owns(p_rid)) { _update_dirty_skeletons(); - skeleton_allocate(p_rid, 0); + skeleton_allocate_data(p_rid, 0); Skeleton *skeleton = skeleton_owner.getornull(p_rid); skeleton->dependency.deleted_notify(p_rid); skeleton_owner.free(p_rid); @@ -8241,7 +8302,7 @@ bool RendererStorageRD::free(RID p_rid) { decal->dependency.deleted_notify(p_rid); decal_owner.free(p_rid); } else if (gi_probe_owner.owns(p_rid)) { - gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate + gi_probe_allocate_data(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); gi_probe->dependency.deleted_notify(p_rid); gi_probe_owner.free(p_rid); @@ -8847,9 +8908,11 @@ RendererStorageRD::RendererStorageRD() { { // default material and shader for particles shader - particles_shader.default_shader = shader_create(); + particles_shader.default_shader = shader_allocate(); + shader_initialize(particles_shader.default_shader); shader_set_code(particles_shader.default_shader, "shader_type particles; void compute() { COLOR = vec4(1.0); } \n"); - particles_shader.default_material = material_create(); + particles_shader.default_material = material_allocate(); + material_initialize(particles_shader.default_material); material_set_shader(particles_shader.default_material, particles_shader.default_shader); ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RendererStorageRD::SHADER_TYPE_PARTICLES); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index aa7195232a..68256dc155 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -221,7 +221,7 @@ private: ~CanvasTexture(); }; - RID_PtrOwner<CanvasTexture> canvas_texture_owner; + RID_PtrOwner<CanvasTexture, true> canvas_texture_owner; /* TEXTURE API */ struct Texture { @@ -367,7 +367,7 @@ private: }; ShaderDataRequestFunction shader_data_request_func[SHADER_TYPE_MAX]; - mutable RID_Owner<Shader> shader_owner; + mutable RID_Owner<Shader, true> shader_owner; /* Material */ @@ -389,7 +389,7 @@ private: }; MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX]; - mutable RID_Owner<Material> material_owner; + mutable RID_Owner<Material, true> material_owner; Material *material_update_list; void _material_queue_update(Material *material, bool p_uniform, bool p_texture); @@ -484,7 +484,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Mesh> mesh_owner; + mutable RID_Owner<Mesh, true> mesh_owner; struct MeshInstance { Mesh *mesh; @@ -587,7 +587,7 @@ private: Dependency dependency; }; - mutable RID_Owner<MultiMesh> multimesh_owner; + mutable RID_Owner<MultiMesh, true> multimesh_owner; MultiMesh *multimesh_dirty_list = nullptr; @@ -893,7 +893,7 @@ private: void update_particles(); - mutable RID_Owner<Particles> particles_owner; + mutable RID_Owner<Particles, true> particles_owner; /* Particles Collision */ @@ -915,7 +915,7 @@ private: Dependency dependency; }; - mutable RID_Owner<ParticlesCollision> particles_collision_owner; + mutable RID_Owner<ParticlesCollision, true> particles_collision_owner; struct ParticlesCollisionInstance { RID collision; @@ -945,7 +945,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Skeleton> skeleton_owner; + mutable RID_Owner<Skeleton, true> skeleton_owner; _FORCE_INLINE_ void _skeleton_make_dirty(Skeleton *skeleton); @@ -977,7 +977,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Light> light_owner; + mutable RID_Owner<Light, true> light_owner; /* REFLECTION PROBE */ @@ -1000,7 +1000,7 @@ private: Dependency dependency; }; - mutable RID_Owner<ReflectionProbe> reflection_probe_owner; + mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner; /* DECAL */ @@ -1021,7 +1021,7 @@ private: Dependency dependency; }; - mutable RID_Owner<Decal> decal_owner; + mutable RID_Owner<Decal, true> decal_owner; /* GI PROBE */ @@ -1064,7 +1064,7 @@ private: RID giprobe_sdf_shader_version_shader; RID giprobe_sdf_shader_pipeline; - mutable RID_Owner<GIProbe> gi_probe_owner; + mutable RID_Owner<GIProbe, true> gi_probe_owner; /* REFLECTION PROBE */ @@ -1095,7 +1095,7 @@ private: uint64_t lightmap_array_version = 0; - mutable RID_Owner<Lightmap> lightmap_owner; + mutable RID_Owner<Lightmap, true> lightmap_owner; float lightmap_probe_capture_update_speed = 4; @@ -1249,12 +1249,16 @@ private: EffectsRD effects; public: + virtual bool can_create_resources_async() const; + /* TEXTURE API */ - virtual RID texture_2d_create(const Ref<Image> &p_image); - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type); - virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent - virtual RID texture_proxy_create(RID p_base); + virtual RID texture_allocate(); + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image); + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type); + virtual void texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent + virtual void texture_proxy_initialize(RID p_texture, RID p_base); virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate); @@ -1264,9 +1268,9 @@ public: virtual void texture_proxy_update(RID p_texture, RID p_proxy_to); //these two APIs can be used together or in combination with the others. - virtual RID texture_2d_placeholder_create(); - virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type); - virtual RID texture_3d_placeholder_create(); + virtual void texture_2d_placeholder_initialize(RID p_texture); + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type); + virtual void texture_3d_placeholder_initialize(RID p_texture); virtual Ref<Image> texture_2d_get(RID p_texture) const; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const; @@ -1338,7 +1342,8 @@ public: /* CANVAS TEXTURE API */ - virtual RID canvas_texture_create(); + RID canvas_texture_allocate(); + void canvas_texture_initialize(RID p_canvas_texture); virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture); virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess); @@ -1350,7 +1355,8 @@ public: /* SHADER API */ - RID shader_create(); + RID shader_allocate(); + void shader_initialize(RID p_shader); void shader_set_code(RID p_shader, const String &p_code); String shader_get_code(RID p_shader) const; @@ -1365,7 +1371,8 @@ public: /* COMMON MATERIAL API */ - RID material_create(); + RID material_allocate(); + void material_initialize(RID p_material); void material_set_shader(RID p_material, RID p_shader); @@ -1401,7 +1408,8 @@ public: /* MESH API */ - virtual RID mesh_create(); + RID mesh_allocate(); + void mesh_initialize(RID p_mesh); virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count); @@ -1482,13 +1490,7 @@ public: return s->lod_count > 0; } - _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface) const { - Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); - - return s->index_array; - } - - _FORCE_INLINE_ RID mesh_surface_get_index_array_with_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const { + _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const { Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); int32_t current_lod = -1; @@ -1500,9 +1502,19 @@ public: current_lod = i; } if (current_lod == -1) { + return 0; + } else { + return current_lod + 1; + } + } + + _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface, uint32_t p_lod) const { + Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); + + if (p_lod == 0) { return s->index_array; } else { - return s->lods[current_lod].index_array; + return s->lods[p_lod - 1].index_array; } } @@ -1618,9 +1630,10 @@ public: /* MULTIMESH API */ - RID multimesh_create(); + RID multimesh_allocate(); + void multimesh_initialize(RID p_multimesh); - void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false); + void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false); int multimesh_get_instance_count(RID p_multimesh) const; void multimesh_set_mesh(RID p_multimesh, RID p_mesh); @@ -1684,24 +1697,28 @@ public: /* IMMEDIATE API */ - RID immediate_create() { return RID(); } - void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {} - void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {} - void immediate_normal(RID p_immediate, const Vector3 &p_normal) {} - void immediate_tangent(RID p_immediate, const Plane &p_tangent) {} - void immediate_color(RID p_immediate, const Color &p_color) {} - void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {} - void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {} - void immediate_end(RID p_immediate) {} - void immediate_clear(RID p_immediate) {} - void immediate_set_material(RID p_immediate, RID p_material) {} - RID immediate_get_material(RID p_immediate) const { return RID(); } - AABB immediate_get_aabb(RID p_immediate) const { return AABB(); } + RID immediate_allocate() { return RID(); } + void immediate_initialize(RID p_immediate) {} + + virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {} + virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {} + virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) {} + virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) {} + virtual void immediate_color(RID p_immediate, const Color &p_color) {} + virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {} + virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {} + virtual void immediate_end(RID p_immediate) {} + virtual void immediate_clear(RID p_immediate) {} + virtual void immediate_set_material(RID p_immediate, RID p_material) {} + virtual RID immediate_get_material(RID p_immediate) const { return RID(); } + virtual AABB immediate_get_aabb(RID p_immediate) const { return AABB(); } /* SKELETON API */ - RID skeleton_create(); - void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false); + RID skeleton_allocate(); + void skeleton_initialize(RID p_skeleton); + + void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false); void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform); void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform); int skeleton_get_bone_count(RID p_skeleton) const; @@ -1735,11 +1752,16 @@ public: } /* Light API */ - RID light_create(RS::LightType p_type); + void _light_initialize(RID p_rid, RS::LightType p_type); - RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); } - RID omni_light_create() { return light_create(RS::LIGHT_OMNI); } - RID spot_light_create() { return light_create(RS::LIGHT_SPOT); } + RID directional_light_allocate(); + void directional_light_initialize(RID p_light); + + RID omni_light_allocate(); + void omni_light_initialize(RID p_light); + + RID spot_light_allocate(); + void spot_light_initialize(RID p_light); void light_set_color(RID p_light, const Color &p_color); void light_set_param(RID p_light, RS::LightParam p_param, float p_value); @@ -1842,7 +1864,8 @@ public: /* PROBE API */ - RID reflection_probe_create(); + RID reflection_probe_allocate(); + void reflection_probe_initialize(RID p_reflection_probe); void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode); void reflection_probe_set_intensity(RID p_probe, float p_intensity); @@ -1882,7 +1905,9 @@ public: /* DECAL API */ - virtual RID decal_create(); + RID decal_allocate(); + void decal_initialize(RID p_decal); + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents); virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture); virtual void decal_set_emission_energy(RID p_decal, float p_energy); @@ -1957,9 +1982,10 @@ public: /* GI PROBE API */ - RID gi_probe_create(); + RID gi_probe_allocate(); + void gi_probe_initialize(RID p_gi_probe); - void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); + void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); AABB gi_probe_get_bounds(RID p_gi_probe) const; Vector3i gi_probe_get_octree_size(RID p_gi_probe) const; @@ -2010,7 +2036,8 @@ public: /* LIGHTMAP CAPTURE */ - virtual RID lightmap_create(); + RID lightmap_allocate(); + void lightmap_initialize(RID p_lightmap); virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics); virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds); @@ -2059,7 +2086,8 @@ public: /* PARTICLES */ - RID particles_create(); + RID particles_allocate(); + void particles_initialize(RID p_particles_collision); void particles_set_emitting(RID p_particles, bool p_emitting); void particles_set_amount(RID p_particles, int p_amount); @@ -2137,7 +2165,9 @@ public: /* PARTICLES COLLISION */ - virtual RID particles_collision_create(); + RID particles_collision_allocate(); + void particles_collision_initialize(RID p_particles_collision); + virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type); virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask); virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius); //for spheres diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index e77141b26c..a81706700a 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -687,7 +687,15 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uint32_t index = p_default_actions.base_varying_index; + List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light; + for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { + if (E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) { + var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(E->key(), E->get())); + fragment_varyings.insert(E->key()); + continue; + } + String vcode; String interp_mode = _interpstr(E->get().interpolation); vcode += _prestr(E->get().precision); @@ -705,6 +713,21 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge index++; } + if (var_frag_to_light.size() > 0) { + String gcode = "\n\nstruct {\n"; + for (List<Pair<StringName, SL::ShaderNode::Varying>>::Element *E = var_frag_to_light.front(); E; E = E->next()) { + gcode += "\t" + _prestr(E->get().second.precision) + _typestr(E->get().second.type) + " " + _mkid(E->get().first); + if (E->get().second.array_size > 0) { + gcode += "["; + gcode += itos(E->get().second.array_size); + gcode += "]"; + } + gcode += ";\n"; + } + gcode += "} frag_to_light;\n"; + r_gen_code.fragment_global += gcode; + } + for (int i = 0; i < pnode->vconstants.size(); i++) { const SL::ShaderNode::Constant &cnode = pnode->vconstants[i]; String gcode; @@ -833,6 +856,19 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; case SL::Node::TYPE_VARIABLE: { SL::VariableNode *vnode = (SL::VariableNode *)p_node; + bool use_fragment_varying = false; + + if (current_func_name != vertex_name) { + if (p_assigning) { + if (shader->varyings.has(vnode->name)) { + use_fragment_varying = true; + } + } else { + if (fragment_varyings.has(vnode->name)) { + use_fragment_varying = true; + } + } + } if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) { *p_actions.write_flag_pointers[vnode->name] = true; @@ -877,7 +913,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } } else { - code = _mkid(vnode->name); //its something else (local var most likely) use as is + if (use_fragment_varying) { + code = "frag_to_light."; + } + code += _mkid(vnode->name); //its something else (local var most likely) use as is } } @@ -962,6 +1001,23 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; case SL::Node::TYPE_ARRAY: { SL::ArrayNode *anode = (SL::ArrayNode *)p_node; + bool use_fragment_varying = false; + + if (current_func_name != vertex_name) { + if (anode->assign_expression != nullptr) { + use_fragment_varying = true; + } else { + if (p_assigning) { + if (shader->varyings.has(anode->name)) { + use_fragment_varying = true; + } + } else { + if (fragment_varyings.has(anode->name)) { + use_fragment_varying = true; + } + } + } + } if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) { *p_actions.write_flag_pointers[anode->name] = true; @@ -984,7 +1040,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (p_default_actions.renames.has(anode->name)) { code = p_default_actions.renames[anode->name]; } else { - code = _mkid(anode->name); + if (use_fragment_varying) { + code = "frag_to_light."; + } + code += _mkid(anode->name); } if (anode->call_expression != nullptr) { @@ -1277,6 +1336,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide used_name_defines.clear(); used_rmode_defines.clear(); used_flag_pointers.clear(); + fragment_varyings.clear(); shader = parser.get_shader(); function = nullptr; diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h index d127d8e01c..6575829e73 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.h +++ b/servers/rendering/renderer_rd/shader_compiler_rd.h @@ -114,6 +114,7 @@ private: Set<StringName> used_flag_pointers; Set<StringName> used_rmode_defines; Set<StringName> internal_functions; + Set<StringName> fragment_varyings; DefaultIdentifierActions actions; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 2ae22a8a38..e4a39ff813 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -301,6 +301,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { builder.append(compute_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline + builder.append(base_compute_defines.get_data()); builder.append(general_defines.get_data()); builder.append(variant_defines[p_variant].get_data()); @@ -401,7 +402,6 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio builder.append(fragment_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline - builder.append(general_defines.get_data()); builder.append(variant_defines[i].get_data()); for (int j = 0; j < version->custom_defines.size(); j++) { @@ -440,6 +440,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio builder.append(compute_codev.get_data()); // version info (if exists) builder.append("\n"); //make sure defines begin at newline + builder.append(base_compute_defines.get_data()); builder.append(general_defines.get_data()); builder.append(variant_defines[i].get_data()); @@ -596,6 +597,22 @@ bool ShaderRD::is_variant_enabled(int p_variant) const { return variants_enabled[p_variant]; } +ShaderRD::ShaderRD() { + // Do not feel forced to use this, in most cases it makes little to no difference. + bool use_32_threads = false; + if (RD::get_singleton()->get_device_vendor_name() == "NVIDIA") { + use_32_threads = true; + } + String base_compute_define_text; + if (use_32_threads) { + base_compute_define_text = "\n#define NATIVE_LOCAL_GROUP_SIZE 32\n#define NATIVE_LOCAL_SIZE_2D_X 8\n#define NATIVE_LOCAL_SIZE_2D_Y 4\n"; + } else { + base_compute_define_text = "\n#define NATIVE_LOCAL_GROUP_SIZE 64\n#define NATIVE_LOCAL_SIZE_2D_X 8\n#define NATIVE_LOCAL_SIZE_2D_Y 8\n"; + } + + base_compute_defines = base_compute_define_text.ascii(); +} + void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) { ERR_FAIL_COND(variant_defines.size()); ERR_FAIL_COND(p_variant_defines.size() == 0); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index a3474c6f93..e0f4dcf2d0 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -99,8 +99,10 @@ class ShaderRD { const char *name; + CharString base_compute_defines; + protected: - ShaderRD() {} + ShaderRD(); void setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name); public: diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub index 1b0197c1c1..c192574ff2 100644 --- a/servers/rendering/renderer_rd/shaders/SCsub +++ b/servers/rendering/renderer_rd/shaders/SCsub @@ -39,7 +39,6 @@ if "RD_GLSL" in env["BUILDERS"]: env.RD_GLSL("sdfgi_debug.glsl") env.RD_GLSL("sdfgi_debug_probes.glsl") env.RD_GLSL("volumetric_fog.glsl") - env.RD_GLSL("shadow_reduce.glsl") env.RD_GLSL("particles.glsl") env.RD_GLSL("particles_copy.glsl") env.RD_GLSL("sort.glsl") diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index 35522103df..92a5682572 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl @@ -363,57 +363,62 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o ray_pos += (ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) + cam_normal * 1.4) * bias / sdfgi.cascades[cascade].to_cell; } float softness = 0.2 + min(1.0, roughness * 5.0) * 4.0; //approximation to roughness so it does not seem like a hard fade - while (length(ray_pos) < max_distance) { - for (uint i = 0; i < sdfgi.max_cascades; i++) { - if (i >= cascade && length(ray_pos) < radius_sizes[i]) { - cascade = max(i, cascade); //never go down - - vec3 pos = ray_pos - sdfgi.cascades[i].position; - pos *= sdfgi.cascades[i].to_cell * pos_to_uvw; - - float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.1; - - vec4 hit_light = vec4(0.0); - if (distance < softness) { - hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb; - hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy - hit_light.a = clamp(1.0 - (distance / softness), 0.0, 1.0); - hit_light.rgb *= hit_light.a; - } + uint i = 0; + bool found = false; + while (true) { + if (length(ray_pos) >= max_distance || light_accum.a > 0.99) { + break; + } + if (!found && i >= cascade && length(ray_pos) < radius_sizes[i]) { + uint next_i = min(i + 1, sdfgi.max_cascades - 1); + cascade = max(i, cascade); //never go down - distance /= sdfgi.cascades[i].to_cell; + vec3 pos = ray_pos - sdfgi.cascades[i].position; + pos *= sdfgi.cascades[i].to_cell * pos_to_uvw; - if (i < (sdfgi.max_cascades - 1)) { - pos = ray_pos - sdfgi.cascades[i + 1].position; - pos *= sdfgi.cascades[i + 1].to_cell * pos_to_uvw; + float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).r * 255.0 - 1.1; - float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.1; + vec4 hit_light = vec4(0.0); + if (fdistance < softness) { + hit_light.rgb = textureLod(sampler3D(light_cascades[i], linear_sampler), pos, 0.0).rgb; + hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy + hit_light.a = clamp(1.0 - (fdistance / softness), 0.0, 1.0); + hit_light.rgb *= hit_light.a; + } - vec4 hit_light2 = vec4(0.0); - if (distance2 < softness) { - hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb; - hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy - hit_light2.a = clamp(1.0 - (distance2 / softness), 0.0, 1.0); - hit_light2.rgb *= hit_light2.a; - } + fdistance /= sdfgi.cascades[i].to_cell; - float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1]; - float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0); + if (i < (sdfgi.max_cascades - 1)) { + pos = ray_pos - sdfgi.cascades[next_i].position; + pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw; - distance2 /= sdfgi.cascades[i + 1].to_cell; + float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1; - hit_light = mix(hit_light, hit_light2, blend); - distance = mix(distance, distance2, blend); + vec4 hit_light2 = vec4(0.0); + if (fdistance2 < softness) { + hit_light2.rgb = textureLod(sampler3D(light_cascades[next_i], linear_sampler), pos, 0.0).rgb; + hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy + hit_light2.a = clamp(1.0 - (fdistance2 / softness), 0.0, 1.0); + hit_light2.rgb *= hit_light2.a; } - light_accum += hit_light; - ray_pos += ray_dir * distance; - break; + float prev_radius = i == 0 ? 0.0 : radius_sizes[max(0, i - 1)]; + float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0); + + fdistance2 /= sdfgi.cascades[next_i].to_cell; + + hit_light = mix(hit_light, hit_light2, blend); + fdistance = mix(fdistance, fdistance2, blend); } - } - if (light_accum.a > 0.99) { - break; + light_accum += hit_light; + ray_pos += ray_dir * fdistance; + found = true; + } + i++; + if (i == sdfgi.max_cascades) { + i = 0; + found = false; } } diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl index 4f4753d147..b931461b31 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl @@ -51,10 +51,10 @@ struct Light { float attenuation; vec3 color; - float spot_angle_radians; + float cos_spot_angle; vec3 position; - float spot_attenuation; + float inv_spot_attenuation; vec3 direction; bool has_shadow; @@ -233,13 +233,15 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 if (lights.data[light].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(pos - light_pos); - float angle = acos(dot(rel, lights.data[light].direction)); - if (angle > lights.data[light].spot_angle_radians) { + float cos_spot_angle = lights.data[light].cos_spot_angle; + float cos_angle = dot(rel, lights.data[light].direction); + if (cos_angle < cos_spot_angle) { return false; } - float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1); - attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation); + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation); } } diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl index 9c794f1bcc..56b3b7ccb4 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl @@ -43,10 +43,10 @@ struct Light { float attenuation; vec3 color; - float spot_angle_radians; + float cos_spot_angle; vec3 position; - float spot_attenuation; + float inv_spot_attenuation; vec3 direction; bool has_shadow; @@ -146,13 +146,15 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation if (lights.data[light].type == LIGHT_TYPE_SPOT) { vec3 rel = normalize(pos - light_pos); - float angle = acos(dot(rel, lights.data[light].direction)); - if (angle > lights.data[light].spot_angle_radians) { + float cos_spot_angle = lights.data[light].cos_spot_angle; + float cos_angle = dot(rel, lights.data[light].direction); + if (cos_angle < cos_spot_angle) { return false; } - float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1); - attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation); + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation); } } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward.glsl b/servers/rendering/renderer_rd/shaders/scene_forward.glsl index ea203c8abe..adccf1e712 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward.glsl @@ -89,12 +89,6 @@ MATERIAL_UNIFORMS } material; #endif -/* clang-format off */ - -VERTEX_SHADER_GLOBALS - -/* clang-format on */ - invariant gl_Position; #ifdef MODE_DUAL_PARABOLOID @@ -103,28 +97,43 @@ layout(location = 8) out float dp_clip; #endif +layout(location = 9) out flat uint instance_index; + +/* clang-format off */ + +VERTEX_SHADER_GLOBALS + +/* clang-format on */ + void main() { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; #endif - mat4 world_matrix = draw_call.transform; + instance_index = draw_call.instance_index; + + bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH); + if (!is_multimesh) { + instance_index += gl_InstanceIndex; + } + + mat4 world_matrix = instances.data[instance_index].transform; mat3 world_normal_matrix; - if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) { world_normal_matrix = inverse(mat3(world_matrix)); } else { world_normal_matrix = mat3(world_matrix); } - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH)) { + if (is_multimesh) { //multimesh, instances are for it - uint offset = (draw_call.flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK; + uint offset = (instances.data[instance_index].flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK; offset *= gl_InstanceIndex; mat4 matrix; - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); offset += 2; } else { @@ -132,14 +141,14 @@ void main() { offset += 3; } - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { #ifdef COLOR_USED color_interp *= transforms.data[offset]; #endif offset += 1; } - if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { instance_custom = transforms.data[offset]; } @@ -161,7 +170,7 @@ void main() { #endif #if 0 - if (bool(draw_call.flags & INSTANCE_FLAGS_SKELETON)) { + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) { //multimesh, instances are for it uvec2 bones_01 = uvec2(bone_attrib.x & 0xFFFF, bone_attrib.x >> 16) * 3; @@ -194,7 +203,7 @@ void main() { uv2_interp = uv2_attrib; #endif -#ifdef USE_OVERRIDE_POSITION +#ifdef OVERRIDE_POSITION vec4 position; #endif @@ -289,7 +298,7 @@ VERTEX_SHADER_CODE #endif //MODE_RENDER_DEPTH -#ifdef USE_OVERRIDE_POSITION +#ifdef OVERRIDE_POSITION gl_Position = position; #else gl_Position = projection_matrix * vec4(vertex_interp, 1.0); @@ -304,7 +313,8 @@ VERTEX_SHADER_CODE #endif #ifdef MODE_RENDER_MATERIAL if (scene_data.material_uv2_mode) { - gl_Position.xy = (uv2_attrib.xy + draw_call.lightmap_uv_scale.xy) * 2.0 - 1.0; + vec2 uv_offset = unpackHalf2x16(draw_call.uv_offset); + gl_Position.xy = (uv2_attrib.xy + uv_offset) * 2.0 - 1.0; gl_Position.z = 0.00001; gl_Position.w = 1.0; } @@ -350,9 +360,11 @@ layout(location = 8) in float dp_clip; #endif +layout(location = 9) in flat uint instance_index; + //defines to keep compatibility with vertex -#define world_matrix draw_call.transform +#define world_matrix instances.data[instance_index].transform #define projection_matrix scene_data.projection_matrix #if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) @@ -1770,7 +1782,7 @@ vec4 fog_process(vec3 vertex) { } } - float fog_amount = 1.0 - exp(vertex.z * scene_data.fog_density); + float fog_amount = 1.0 - exp(min(0.0, vertex.z * scene_data.fog_density)); if (abs(scene_data.fog_height_density) > 0.001) { float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y; @@ -2083,7 +2095,7 @@ FRAGMENT_SHADER_CODE #endif uint decal_index = 32 * i + bit; - if (!bool(decals.data[decal_index].mask & draw_call.layer_mask)) { + if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -2210,8 +2222,8 @@ FRAGMENT_SHADER_CODE #ifdef USE_LIGHTMAP //lightmap - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture - uint index = draw_call.gi_offset; + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture + uint index = instances.data[instance_index].gi_offset; vec3 wnormal = mat3(scene_data.camera_matrix) * normal; const float c1 = 0.429043; @@ -2230,12 +2242,12 @@ FRAGMENT_SHADER_CODE 2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y + 2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z); - } else if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap - bool uses_sh = bool(draw_call.flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP); - uint ofs = draw_call.gi_offset & 0xFFFF; + } else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap + bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP); + uint ofs = instances.data[instance_index].gi_offset & 0xFFFF; vec3 uvw; - uvw.xy = uv2 * draw_call.lightmap_uv_scale.zw + draw_call.lightmap_uv_scale.xy; - uvw.z = float((draw_call.gi_offset >> 16) & 0xFFFF); + uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy; + uvw.z = float((instances.data[instance_index].gi_offset >> 16) & 0xFFFF); if (uses_sh) { uvw.z *= 4.0; //SH textures use 4 times more data @@ -2244,7 +2256,7 @@ FRAGMENT_SHADER_CODE vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb; vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb; - uint idx = draw_call.gi_offset >> 20; + uint idx = instances.data[instance_index].gi_offset >> 20; vec3 n = normalize(lightmaps.data[idx].normal_xform * normal); ambient_light += lm_light_l0 * 0.282095f; @@ -2264,7 +2276,7 @@ FRAGMENT_SHADER_CODE } #elif defined(USE_FORWARD_GI) - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture //make vertex orientation the world one, but still align to camera vec3 cam_pos = mat3(scene_data.camera_matrix) * vertex; @@ -2336,9 +2348,9 @@ FRAGMENT_SHADER_CODE } } - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes - uint index1 = draw_call.gi_offset & 0xFFFF; + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); //find arbitrary tangent and bitangent, then build a matrix vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); @@ -2350,7 +2362,7 @@ FRAGMENT_SHADER_CODE vec4 spec_accum = vec4(0.0); gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); - uint index2 = draw_call.gi_offset >> 16; + uint index2 = instances.data[instance_index].gi_offset >> 16; if (index2 != 0xFFFF) { gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); @@ -2369,7 +2381,7 @@ FRAGMENT_SHADER_CODE } #elif !defined(LOW_END_MODE) - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers vec2 coord; @@ -2448,7 +2460,7 @@ FRAGMENT_SHADER_CODE #endif uint reflection_index = 32 * i + bit; - if (!bool(reflections.data[reflection_index].mask & draw_call.layer_mask)) { + if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -2519,7 +2531,7 @@ FRAGMENT_SHADER_CODE break; } - if (!bool(directional_lights.data[i].mask & draw_call.layer_mask)) { + if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -2838,7 +2850,7 @@ FRAGMENT_SHADER_CODE break; } - if (!bool(directional_lights.data[i].mask & draw_call.layer_mask)) { + if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -2968,7 +2980,7 @@ FRAGMENT_SHADER_CODE #endif uint light_index = 32 * i + bit; - if (!bool(omni_lights.data[light_index].mask & draw_call.layer_mask)) { + if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -3041,7 +3053,7 @@ FRAGMENT_SHADER_CODE uint light_index = 32 * i + bit; - if (!bool(spot_lights.data[light_index].mask & draw_call.layer_mask)) { + if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -3214,9 +3226,9 @@ FRAGMENT_SHADER_CODE normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); #ifdef MODE_RENDER_GIPROBE - if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes - uint index1 = draw_call.gi_offset & 0xFFFF; - uint index2 = draw_call.gi_offset >> 16; + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; + uint index2 = instances.data[instance_index].gi_offset >> 16; giprobe_buffer.x = index1 & 0xFF; giprobe_buffer.y = index2 & 0xFF; } else { @@ -3275,6 +3287,7 @@ FRAGMENT_SHADER_CODE // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); + ; #endif //MODE_MULTIPLE_RENDER_TARGETS diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl index e9b79e1560..d78890fa9e 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl @@ -21,12 +21,10 @@ #endif layout(push_constant, binding = 0, std430) uniform DrawCall { - mat4 transform; - uint flags; - uint instance_uniforms_ofs; //base offset in global buffer for instance variables - uint gi_offset; //GI information when using lightmapping (VCT or lightmap index) - uint layer_mask; - vec4 lightmap_uv_scale; + uint instance_index; + uint uv_offset; + uint pad0; + uint pad1; } draw_call; @@ -45,96 +43,13 @@ draw_call; #define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT 10 #define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11 -layout(set = 0, binding = 1) uniform sampler material_samplers[12]; - -layout(set = 0, binding = 2) uniform sampler shadow_sampler; - #define SDFGI_MAX_CASCADES 8 -layout(set = 0, binding = 3, std140) uniform SceneData { - mat4 projection_matrix; - mat4 inv_projection_matrix; - - mat4 camera_matrix; - mat4 inv_camera_matrix; - - vec2 viewport_size; - vec2 screen_pixel_size; - - uint cluster_shift; - uint cluster_width; - uint cluster_type_size; - uint max_cluster_element_count_div_32; - - //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted - vec4 directional_penumbra_shadow_kernel[32]; - vec4 directional_soft_shadow_kernel[32]; - vec4 penumbra_shadow_kernel[32]; - vec4 soft_shadow_kernel[32]; - - uint directional_penumbra_shadow_samples; - uint directional_soft_shadow_samples; - uint penumbra_shadow_samples; - uint soft_shadow_samples; - - vec4 ambient_light_color_energy; +/* Set 1: Base Pass (never changes) */ - float ambient_color_sky_mix; - bool use_ambient_light; - bool use_ambient_cubemap; - bool use_reflection_cubemap; - - mat3 radiance_inverse_xform; - - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; - - uint directional_light_count; - float dual_paraboloid_side; - float z_far; - float z_near; - - bool ssao_enabled; - float ssao_light_affect; - float ssao_ao_affect; - bool roughness_limiter_enabled; - - float roughness_limiter_amount; - float roughness_limiter_limit; - uvec2 roughness_limiter_pad; - - vec4 ao_color; - - mat4 sdf_to_bounds; - - ivec3 sdf_offset; - bool material_uv2_mode; - - ivec3 sdf_size; - bool gi_upscale_for_msaa; - - bool volumetric_fog_enabled; - float volumetric_fog_inv_length; - float volumetric_fog_detail_spread; - uint volumetric_fog_pad; - - bool fog_enabled; - float fog_density; - float fog_height; - float fog_height_density; - - vec3 fog_light_color; - float fog_sun_scatter; - - float fog_aerial_perspective; - - float time; - float reflection_multiplier; // one normally, zero when rendering reflections - - bool pancake_shadows; -} +layout(set = 0, binding = 1) uniform sampler material_samplers[12]; -scene_data; +layout(set = 0, binding = 2) uniform sampler shadow_sampler; #define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6) #define INSTANCE_FLAGS_USE_SDFGI (1 << 7) @@ -153,22 +68,22 @@ scene_data; #define INSTANCE_FLAGS_SKELETON (1 << 19) #define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20) -layout(set = 0, binding = 4, std430) restrict readonly buffer OmniLights { +layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights { LightData data[]; } omni_lights; -layout(set = 0, binding = 5, std430) restrict readonly buffer SpotLights { +layout(set = 0, binding = 4, std430) restrict readonly buffer SpotLights { LightData data[]; } spot_lights; -layout(set = 0, binding = 6) buffer restrict readonly ReflectionProbeData { +layout(set = 0, binding = 5) buffer restrict readonly ReflectionProbeData { ReflectionData data[]; } reflections; -layout(set = 0, binding = 7, std140) uniform DirectionalLights { +layout(set = 0, binding = 6, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } directional_lights; @@ -180,7 +95,7 @@ struct Lightmap { mat3 normal_xform; }; -layout(set = 0, binding = 8, std140) restrict readonly buffer Lightmaps { +layout(set = 0, binding = 7, std140) restrict readonly buffer Lightmaps { Lightmap data[]; } lightmaps; @@ -189,20 +104,20 @@ struct LightmapCapture { vec4 sh[9]; }; -layout(set = 0, binding = 9, std140) restrict readonly buffer LightmapCaptures { +layout(set = 0, binding = 8, std140) restrict readonly buffer LightmapCaptures { LightmapCapture data[]; } lightmap_captures; -layout(set = 0, binding = 10) uniform texture2D decal_atlas; -layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 9) uniform texture2D decal_atlas; +layout(set = 0, binding = 10) uniform texture2D decal_atlas_srgb; -layout(set = 0, binding = 12, std430) restrict readonly buffer Decals { +layout(set = 0, binding = 11, std430) restrict readonly buffer Decals { DecalData data[]; } decals; -layout(set = 0, binding = 13, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } global_variables; @@ -216,7 +131,7 @@ struct SDFGIProbeCascadeData { float to_cell; // 1/bounds * grid_size }; -layout(set = 0, binding = 14, std140) uniform SDFGI { +layout(set = 0, binding = 13, std140) uniform SDFGI { vec3 grid_size; uint max_cascades; @@ -246,47 +161,140 @@ sdfgi; #endif //LOW_END_MODE -// decal atlas +/* Set 2: Render Pass (changes per render pass) */ -/* Set 1, Radiance */ +layout(set = 1, binding = 0, std140) uniform SceneData { + mat4 projection_matrix; + mat4 inv_projection_matrix; + + mat4 camera_matrix; + mat4 inv_camera_matrix; + + vec2 viewport_size; + vec2 screen_pixel_size; + + uint cluster_shift; + uint cluster_width; + uint cluster_type_size; + uint max_cluster_element_count_div_32; + + //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + vec4 directional_penumbra_shadow_kernel[32]; + vec4 directional_soft_shadow_kernel[32]; + vec4 penumbra_shadow_kernel[32]; + vec4 soft_shadow_kernel[32]; + + uint directional_penumbra_shadow_samples; + uint directional_soft_shadow_samples; + uint penumbra_shadow_samples; + uint soft_shadow_samples; + + vec4 ambient_light_color_energy; + + float ambient_color_sky_mix; + bool use_ambient_light; + bool use_ambient_cubemap; + bool use_reflection_cubemap; + + mat3 radiance_inverse_xform; + + vec2 shadow_atlas_pixel_size; + vec2 directional_shadow_pixel_size; + + uint directional_light_count; + float dual_paraboloid_side; + float z_far; + float z_near; + + bool ssao_enabled; + float ssao_light_affect; + float ssao_ao_affect; + bool roughness_limiter_enabled; + + float roughness_limiter_amount; + float roughness_limiter_limit; + uvec2 roughness_limiter_pad; + + vec4 ao_color; + + mat4 sdf_to_bounds; + + ivec3 sdf_offset; + bool material_uv2_mode; + + ivec3 sdf_size; + bool gi_upscale_for_msaa; + + bool volumetric_fog_enabled; + float volumetric_fog_inv_length; + float volumetric_fog_detail_spread; + uint volumetric_fog_pad; + + bool fog_enabled; + float fog_density; + float fog_height; + float fog_height_density; + + vec3 fog_light_color; + float fog_sun_scatter; + + float fog_aerial_perspective; + + float time; + float reflection_multiplier; // one normally, zero when rendering reflections + + bool pancake_shadows; +} + +scene_data; + +struct InstanceData { + mat4 transform; + uint flags; + uint instance_uniforms_ofs; //base offset in global buffer for instance variables + uint gi_offset; //GI information when using lightmapping (VCT or lightmap index) + uint layer_mask; + vec4 lightmap_uv_scale; +}; + +layout(set = 1, binding = 1, std430) buffer restrict readonly InstanceDataBuffer { + InstanceData data[]; +} +instances; #ifdef USE_RADIANCE_CUBEMAP_ARRAY -layout(set = 1, binding = 0) uniform textureCubeArray radiance_cubemap; +layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap; #else -layout(set = 1, binding = 0) uniform textureCube radiance_cubemap; +layout(set = 1, binding = 2) uniform textureCube radiance_cubemap; #endif -/* Set 2, Reflection and Shadow Atlases (view dependent) */ - -layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas; +layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas; -layout(set = 1, binding = 2) uniform texture2D shadow_atlas; +layout(set = 1, binding = 4) uniform texture2D shadow_atlas; -layout(set = 1, binding = 3) uniform texture2D directional_shadow_atlas; +layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; -layout(set = 1, binding = 4) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; +layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; -#ifndef LOW_END_MODE -layout(set = 1, binding = 5) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +#ifndef LOW_END_MOD +layout(set = 1, binding = 7) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; #endif -layout(set = 1, binding = 6, std430) buffer restrict readonly ClusterBuffer { +layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer { uint data[]; } cluster_buffer; -/* Set 3, Render Buffers */ - #ifdef MODE_RENDER_SDF -layout(r16ui, set = 1, binding = 7) uniform restrict writeonly uimage3D albedo_volume_grid; -layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_grid; -layout(r32ui, set = 1, binding = 9) uniform restrict writeonly uimage3D emission_aniso_grid; -layout(r32ui, set = 1, binding = 10) uniform restrict uimage3D geom_facing_grid; +layout(r16ui, set = 1, binding = 9) uniform restrict writeonly uimage3D albedo_volume_grid; +layout(r32ui, set = 1, binding = 10) uniform restrict writeonly uimage3D emission_grid; +layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_aniso_grid; +layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid; //still need to be present for shaders that use it, so remap them to something #define depth_buffer shadow_atlas @@ -295,17 +303,17 @@ layout(r32ui, set = 1, binding = 10) uniform restrict uimage3D geom_facing_grid; #else -layout(set = 1, binding = 7) uniform texture2D depth_buffer; -layout(set = 1, binding = 8) uniform texture2D color_buffer; +layout(set = 1, binding = 9) uniform texture2D depth_buffer; +layout(set = 1, binding = 10) uniform texture2D color_buffer; #ifndef LOW_END_MODE -layout(set = 1, binding = 9) uniform texture2D normal_roughness_buffer; -layout(set = 1, binding = 10) uniform texture2D ao_buffer; -layout(set = 1, binding = 11) uniform texture2D ambient_buffer; -layout(set = 1, binding = 12) uniform texture2D reflection_buffer; -layout(set = 1, binding = 13) uniform texture2DArray sdfgi_lightprobe_texture; -layout(set = 1, binding = 14) uniform texture3D sdfgi_occlusion_cascades; +layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer; +layout(set = 1, binding = 12) uniform texture2D ao_buffer; +layout(set = 1, binding = 13) uniform texture2D ambient_buffer; +layout(set = 1, binding = 14) uniform texture2D reflection_buffer; +layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture; +layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades; struct GIProbeData { mat4 xform; @@ -323,22 +331,22 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 1, binding = 15, std140) uniform GIProbes { +layout(set = 1, binding = 17, std140) uniform GIProbes { GIProbeData data[MAX_GI_PROBES]; } gi_probes; -layout(set = 1, binding = 16) uniform texture3D volumetric_fog_texture; +layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture; #endif // LOW_END_MODE #endif -/* Set 4 Skeleton & Instancing (Multimesh) */ +/* Set 2 Skeleton & Instancing (can change per item) */ layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms { vec4 data[]; } transforms; -/* Set 5 User Material */ +/* Set 3 User Material */ diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index bcdfe8cc85..dc7238abed 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -67,8 +67,8 @@ struct Light { float attenuation; uint type; - float spot_angle; - float spot_attenuation; + float cos_spot_angle; + float inv_spot_attenuation; float radius; vec4 shadow_color; @@ -80,6 +80,7 @@ layout(set = 0, binding = 9, std140) buffer restrict readonly Lights { lights; layout(set = 0, binding = 10) uniform texture2DArray lightprobe_texture; +layout(set = 0, binding = 11) uniform texture3D occlusion_texture; layout(push_constant, binding = 0, std430) uniform Params { vec3 grid_size; @@ -91,9 +92,9 @@ layout(push_constant, binding = 0, std430) uniform Params { uint process_increment; int probe_axis_size; - bool multibounce; + float bounce_feedback; float y_mult; - uint pad; + bool use_occlusion; } params; @@ -159,7 +160,8 @@ void main() { // Add indirect light first, in order to save computation resources #ifdef MODE_PROCESS_DYNAMIC - if (params.multibounce) { + if (params.bounce_feedback > 0.001) { + vec3 feedback = (params.bounce_feedback < 1.0) ? (albedo * params.bounce_feedback) : mix(albedo, vec3(1.0), params.bounce_feedback - 1.0); vec3 pos = (vec3(positioni) + vec3(0.5)) * float(params.probe_axis_size - 1) / params.grid_size; ivec3 probe_base_pos = ivec3(pos); @@ -172,7 +174,7 @@ void main() { vec3 base_tex_posf = vec3(tex_pos); vec2 tex_pixel_size = 1.0 / vec2(ivec2((OCT_SIZE + 2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE + 2) * params.probe_axis_size)); - vec3 probe_uv_offset = (ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx; + vec3 probe_uv_offset = vec3(ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx; for (uint j = 0; j < 8; j++) { ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1); @@ -192,18 +194,35 @@ void main() { for (uint k = 0; k < 6; k++) { if (bool(valid_aniso & (1 << k))) { vec3 n = aniso_dir[k]; - float weight = trilinear.x * trilinear.y * trilinear.z * max(0.005, dot(n, probe_dir)); - - vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0); - tex_posf.xy *= tex_pixel_size; - - vec3 pos_uvw = tex_posf; - pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy; - pos_uvw.x += float(offset.z) * probe_uv_offset.z; - vec3 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb; - - light_accum[k] += indirect_light * weight; - weight_accum[k] += weight; + float weight = trilinear.x * trilinear.y * trilinear.z * max(0, dot(n, probe_dir)); + + if (weight > 0.0 && params.use_occlusion) { + ivec3 occ_indexv = abs((cascades.data[params.cascade].probe_world_offset + probe_posi) & ivec3(1, 1, 1)) * ivec3(1, 2, 4); + vec4 occ_mask = mix(vec4(0.0), vec4(1.0), equal(ivec4(occ_indexv.x | occ_indexv.y), ivec4(0, 1, 2, 3))); + + vec3 occ_pos = (vec3(positioni) + aniso_dir[k] + vec3(0.5)) / params.grid_size; + occ_pos.z += float(params.cascade); + if (occ_indexv.z != 0) { //z bit is on, means index is >=4, so make it switch to the other half of textures + occ_pos.x += 1.0; + } + occ_pos *= vec3(0.5, 1.0, 1.0 / float(params.max_cascades)); //renormalize + float occlusion = dot(textureLod(sampler3D(occlusion_texture, linear_sampler), occ_pos, 0.0), occ_mask); + + weight *= occlusion; + } + + if (weight > 0.0) { + vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0); + tex_posf.xy *= tex_pixel_size; + + vec3 pos_uvw = tex_posf; + pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy; + pos_uvw.x += float(offset.z) * probe_uv_offset.z; + vec3 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb; + + light_accum[k] += indirect_light * weight; + weight_accum[k] += weight; + } } } } @@ -211,7 +230,7 @@ void main() { for (uint k = 0; k < 6; k++) { if (weight_accum[k] > 0.0) { light_accum[k] /= weight_accum[k]; - light_accum[k] *= albedo; + light_accum[k] *= feedback; } } } @@ -266,13 +285,16 @@ void main() { rel_vec.y /= params.y_mult; attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation); - float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction)); - if (angle > lights.data[i].spot_angle) { - attenuation = 0.0; - } else { - float d = clamp(angle / lights.data[i].spot_angle, 0, 1); - attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation); + float cos_spot_angle = lights.data[i].cos_spot_angle; + float cos_angle = dot(-direction, lights.data[i].direction); + + if (cos_angle < cos_spot_angle) { + continue; } + + float scos = max(cos_angle, cos_spot_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle)); + attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation); } break; } diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index e4f6f4b7ea..007e4c113a 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl @@ -244,20 +244,26 @@ void main() { vec4 light; if (hit) { - const float EPSILON = 0.001; - vec3 hit_normal = normalize(vec3( - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r, - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r, - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r)); - - vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb; - vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw); - vec3 hit_aniso0 = aniso0.rgb; - vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg); - - //one liner magic - light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0))); - light.a = 1.0; + //avoid reading different texture from different threads + for (uint j = params.cascade; j < params.max_cascades; j++) { + if (j == hit_cascade) { + const float EPSILON = 0.001; + vec3 hit_normal = normalize(vec3( + texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r, + texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r, + texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r)); + + vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb; + vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw); + vec3 hit_aniso0 = aniso0.rgb; + vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg); + + //one liner magic + light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0))); + light.a = 1.0; + } + } + } else if (params.sky_mode == SKY_MODE_SKY) { #ifdef USE_CUBEMAP_ARRAY light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates diff --git a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl deleted file mode 100644 index 29443ae7db..0000000000 --- a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl +++ /dev/null @@ -1,105 +0,0 @@ -#[compute] - -#version 450 - -VERSION_DEFINES - -#define BLOCK_SIZE 8 - -layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; - -#ifdef MODE_REDUCE - -shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE]; -const uint swizzle_table[BLOCK_SIZE] = uint[](0, 4, 2, 6, 1, 5, 3, 7); -const uint unswizzle_table[BLOCK_SIZE] = uint[](0, 0, 0, 1, 0, 2, 1, 3); - -#endif - -layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_depth; -layout(r32f, set = 0, binding = 1) uniform restrict writeonly image2D dst_depth; - -layout(push_constant, binding = 1, std430) uniform Params { - ivec2 source_size; - ivec2 source_offset; - uint min_size; - uint gaussian_kernel_version; - ivec2 filter_dir; -} -params; - -void main() { -#ifdef MODE_REDUCE - - uvec2 pos = gl_LocalInvocationID.xy; - - ivec2 image_offset = params.source_offset; - ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy); - uint dst_t = swizzle_table[pos.y] * BLOCK_SIZE + swizzle_table[pos.x]; - tmp_data[dst_t] = imageLoad(source_depth, min(image_pos, params.source_size - ivec2(1))).r; - ivec2 image_size = params.source_size; - - uint t = pos.y * BLOCK_SIZE + pos.x; - - //neighbours - uint size = BLOCK_SIZE; - - do { - groupMemoryBarrier(); - barrier(); - - size >>= 1; - image_size >>= 1; - image_offset >>= 1; - - if (all(lessThan(pos, uvec2(size)))) { - uint nx = t + size; - uint ny = t + (BLOCK_SIZE * size); - uint nxy = ny + size; - - tmp_data[t] += tmp_data[nx]; - tmp_data[t] += tmp_data[ny]; - tmp_data[t] += tmp_data[nxy]; - tmp_data[t] /= 4.0; - } - - } while (size > params.min_size); - - if (all(lessThan(pos, uvec2(size)))) { - image_pos = ivec2(unswizzle_table[size + pos.x], unswizzle_table[size + pos.y]); - image_pos += image_offset + ivec2(gl_WorkGroupID.xy) * int(size); - - image_size = max(ivec2(1), image_size); //in case image size became 0 - - if (all(lessThan(image_pos, uvec2(image_size)))) { - imageStore(dst_depth, image_pos, vec4(tmp_data[t])); - } - } -#endif - -#ifdef MODE_FILTER - - ivec2 image_pos = params.source_offset + ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(image_pos, params.source_size))) { - return; - } - - ivec2 clamp_min = ivec2(params.source_offset); - ivec2 clamp_max = ivec2(params.source_size) - 1; - - //gaussian kernel, size 9, sigma 4 - const int kernel_size = 9; - const float gaussian_kernel[kernel_size * 3] = float[]( - 0.000229, 0.005977, 0.060598, 0.241732, 0.382928, 0.241732, 0.060598, 0.005977, 0.000229, - 0.028532, 0.067234, 0.124009, 0.179044, 0.20236, 0.179044, 0.124009, 0.067234, 0.028532, - 0.081812, 0.101701, 0.118804, 0.130417, 0.134535, 0.130417, 0.118804, 0.101701, 0.081812); - float accum = 0.0; - for (int i = 0; i < kernel_size; i++) { - ivec2 ofs = clamp(image_pos + params.filter_dir * (i - kernel_size / 2), clamp_min, clamp_max); - accum += imageLoad(source_depth, ofs).r * gaussian_kernel[params.gaussian_kernel_version + i]; - } - - imageStore(dst_depth, image_pos, vec4(accum)); - -#endif -} diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index b19f5a9ad3..d675e548d7 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -100,7 +100,7 @@ void main() { for (uint i = 0; i < params.blend_shape_count; i++) { float w = blend_shape_weights.data[i]; - if (w > 0.0001) { + if ((w < 0.0001) || (w > 0.0001)) { uint base_offset = (params.vertex_count * i + index) * params.vertex_stride; blend_vertex += uintBitsToFloat(uvec3(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1], src_blend_shapes.data[base_offset + 2])) * w; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index aa32809a06..e7ba8feb80 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl @@ -168,13 +168,18 @@ layout(set = 0, binding = 14, std140) uniform Params { uint cluster_shift; uint cluster_width; - uvec3 cluster_pad; uint max_cluster_element_count_div_32; + bool use_temporal_reprojection; + uint temporal_frame; + float temporal_blend; mat3x4 cam_rotation; + mat4 to_prev_view; } params; +layout(set = 0, binding = 15) uniform texture3D prev_density_texture; + float get_depth_at_pos(float cell_depth_size, int z) { float d = float(z) * cell_depth_size + cell_depth_size * 0.5; //center of voxels d = pow(d, params.detail_spread); @@ -213,6 +218,26 @@ uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) { return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width); } +#define TEMPORAL_FRAMES 16 + +const vec3 halton_map[TEMPORAL_FRAMES] = vec3[]( + vec3(0.5, 0.33333333, 0.2), + vec3(0.25, 0.66666667, 0.4), + vec3(0.75, 0.11111111, 0.6), + vec3(0.125, 0.44444444, 0.8), + vec3(0.625, 0.77777778, 0.04), + vec3(0.375, 0.22222222, 0.24), + vec3(0.875, 0.55555556, 0.44), + vec3(0.0625, 0.88888889, 0.64), + vec3(0.5625, 0.03703704, 0.84), + vec3(0.3125, 0.37037037, 0.08), + vec3(0.8125, 0.7037037, 0.28), + vec3(0.1875, 0.14814815, 0.48), + vec3(0.6875, 0.48148148, 0.68), + vec3(0.4375, 0.81481481, 0.88), + vec3(0.9375, 0.25925926, 0.12), + vec3(0.03125, 0.59259259, 0.32)); + void main() { vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size); @@ -241,6 +266,45 @@ void main() { view_pos.z = -params.fog_frustum_end * fog_unit_pos.z; view_pos.y = -view_pos.y; + vec4 reprojected_density = vec4(0.0); + float reproject_amount = 0.0; + + if (params.use_temporal_reprojection) { + vec3 prev_view = (params.to_prev_view * vec4(view_pos, 1.0)).xyz; + //undo transform into prev view + prev_view.y = -prev_view.y; + //z back to unit size + prev_view.z /= -params.fog_frustum_end; + //xy back to unit size + prev_view.xy /= mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(prev_view.z)); + prev_view.xy = prev_view.xy * 0.5 + 0.5; + //z back to unspread value + prev_view.z = pow(prev_view.z, 1.0 / params.detail_spread); + + if (all(greaterThan(prev_view, vec3(0.0))) && all(lessThan(prev_view, vec3(1.0)))) { + //reprojectinon fits + + reprojected_density = textureLod(sampler3D(prev_density_texture, linear_sampler), prev_view, 0.0); + reproject_amount = params.temporal_blend; + + // Since we can reproject, now we must jitter the current view pos. + // This is done here because cells that can't reproject should not jitter. + + fog_unit_pos = posf * fog_cell_size + fog_cell_size * halton_map[params.temporal_frame]; //center of voxels, offset by halton table + + screen_pos = uvec2(fog_unit_pos.xy * params.screen_size); + cluster_pos = screen_pos >> params.cluster_shift; + cluster_offset = (params.cluster_width * cluster_pos.y + cluster_pos.x) * (params.max_cluster_element_count_div_32 + 32); + //positions in screen are too spread apart, no hopes for optimizing with subgroups + + fog_unit_pos.z = pow(fog_unit_pos.z, params.detail_spread); + + view_pos.xy = (fog_unit_pos.xy * 2.0 - 1.0) * mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(fog_unit_pos.z)); + view_pos.z = -params.fog_frustum_end * fog_unit_pos.z; + view_pos.y = -view_pos.y; + } + } + uint cluster_z = uint(clamp((abs(view_pos.z) / params.z_far) * 32.0, 0.0, 31.0)); vec3 total_light = params.light_color; @@ -433,31 +497,31 @@ void main() { uint light_index = 32 * i + bit; - vec3 light_pos = omni_lights.data[light_index].position; - vec3 light_rel_vec = omni_lights.data[light_index].position - view_pos; + vec3 light_pos = spot_lights.data[light_index].position; + vec3 light_rel_vec = spot_lights.data[light_index].position - view_pos; float d = length(light_rel_vec); float shadow_attenuation = 1.0; - if (d * omni_lights.data[light_index].inv_radius < 1.0) { - float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation); + if (d * spot_lights.data[light_index].inv_radius < 1.0) { + float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation); - vec3 spot_dir = omni_lights.data[light_index].direction; - float scos = max(dot(-normalize(light_rel_vec), spot_dir), omni_lights.data[light_index].cone_angle); - float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - omni_lights.data[light_index].cone_angle)); - attenuation *= 1.0 - pow(spot_rim, omni_lights.data[light_index].cone_attenuation); + vec3 spot_dir = spot_lights.data[light_index].direction; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[light_index].cone_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[light_index].cone_angle)); + attenuation *= 1.0 - pow(spot_rim, spot_lights.data[light_index].cone_attenuation); - vec3 light = omni_lights.data[light_index].color / M_PI; + vec3 light = spot_lights.data[light_index].color / M_PI; - if (omni_lights.data[light_index].shadow_enabled) { + if (spot_lights.data[light_index].shadow_enabled) { //has shadow vec4 v = vec4(view_pos, 1.0); - vec4 splane = (omni_lights.data[light_index].shadow_matrix * v); + vec4 splane = (spot_lights.data[light_index].shadow_matrix * v); splane /= splane.w; float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r; - shadow_attenuation = exp(min(0.0, (depth - splane.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = exp(min(0.0, (depth - splane.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade); } total_light += light * attenuation * shadow_attenuation; @@ -565,7 +629,11 @@ void main() { #endif - imageStore(density_map, pos, vec4(total_light, total_density)); + vec4 final_density = vec4(total_light, total_density); + + final_density = mix(final_density, reprojected_density, reproject_amount); + + imageStore(density_map, pos, final_density); #endif #ifdef MODE_FOG diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index d92642886c..b546001843 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -36,7 +36,8 @@ class RendererScene { public: - virtual RID camera_create() = 0; + virtual RID camera_allocate() = 0; + virtual void camera_initialize(RID p_rid) = 0; virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0; virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0; @@ -48,7 +49,8 @@ public: virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0; virtual bool is_camera(RID p_camera) const = 0; - virtual RID scenario_create() = 0; + virtual RID scenario_allocate() = 0; + virtual void scenario_initialize(RID p_rid) = 0; virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) = 0; virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0; @@ -58,7 +60,8 @@ public: virtual bool is_scenario(RID p_scenario) const = 0; virtual RID scenario_get_environment(RID p_scenario) = 0; - virtual RID instance_create() = 0; + virtual RID instance_allocate() = 0; + virtual void instance_initialize(RID p_rid) = 0; virtual void instance_set_base(RID p_instance, RID p_base) = 0; virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; @@ -99,7 +102,9 @@ public: /* SKY API */ - virtual RID sky_create() = 0; + virtual RID sky_allocate() = 0; + virtual void sky_initialize(RID p_rid) = 0; + virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; @@ -107,7 +112,8 @@ public: /* ENVIRONMENT API */ - virtual RID environment_create() = 0; + virtual RID environment_allocate() = 0; + virtual void environment_initialize(RID p_rid) = 0; virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; virtual void environment_set_sky(RID p_env, RID p_sky) = 0; @@ -122,12 +128,10 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; @@ -136,7 +140,7 @@ public: virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; @@ -161,7 +165,8 @@ public: /* Camera Effects */ - virtual RID camera_effects_create() = 0; + virtual RID camera_effects_allocate() = 0; + virtual void camera_effects_initialize(RID p_rid) = 0; virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; @@ -179,6 +184,7 @@ public: /* Render Buffers */ virtual RID render_buffers_create() = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0; virtual void gi_set_use_half_resolution(bool p_enable) = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index db601ba49c..8a2a1a9eaa 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -39,9 +39,11 @@ /* CAMERA API */ -RID RendererSceneCull::camera_create() { - Camera *camera = memnew(Camera); - return camera_owner.make_rid(camera); +RID RendererSceneCull::camera_allocate() { + return camera_owner.allocate_rid(); +} +void RendererSceneCull::camera_initialize(RID p_rid) { + camera_owner.initialize_rid(p_rid, memnew(Camera)); } void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { @@ -290,11 +292,12 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) { } } -RID RendererSceneCull::scenario_create() { +RID RendererSceneCull::scenario_allocate() { + return scenario_owner.allocate_rid(); +} +void RendererSceneCull::scenario_initialize(RID p_rid) { Scenario *scenario = memnew(Scenario); - ERR_FAIL_COND_V(!scenario, RID()); - RID scenario_rid = scenario_owner.make_rid(scenario); - scenario->self = scenario_rid; + scenario->self = p_rid; scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create(); scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest @@ -307,7 +310,7 @@ RID RendererSceneCull::scenario_create() { scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool); scenario->instance_data.set_page_pool(&instance_data_page_pool); - return scenario_rid; + scenario_owner.initialize_rid(p_rid, scenario); } void RendererSceneCull::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) { @@ -367,14 +370,14 @@ void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_upda _instance_update_list.add(&p_instance->update_item); } -RID RendererSceneCull::instance_create() { +RID RendererSceneCull::instance_allocate() { + return instance_owner.allocate_rid(); +} +void RendererSceneCull::instance_initialize(RID p_rid) { Instance *instance = memnew(Instance); - ERR_FAIL_COND_V(!instance, RID()); + instance->self = p_rid; - RID instance_rid = instance_owner.make_rid(instance); - instance->self = instance_rid; - - return instance_rid; + instance_owner.initialize_rid(p_rid, instance); } void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) { @@ -1906,6 +1909,9 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base); if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) { + if (max_shadows_used + 2 > MAX_UPDATE_SHADOWS) { + return true; + } for (int i = 0; i < 2; i++) { //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); @@ -1922,7 +1928,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius)); planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0)); - geometry_instances_to_shadow_render.clear(); instance_shadow_cull_result.clear(); Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size()); @@ -1943,6 +1948,8 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); + RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; + for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { @@ -1957,16 +1964,21 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } } - geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); + shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); } RSG::storage->update_mesh_instances(); scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); - scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render); + shadow_data.light = light->instance; + shadow_data.pass = i; } } else { //shadow cube + if (max_shadows_used + 6 > MAX_UPDATE_SHADOWS) { + return true; + } + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); CameraMatrix cm; cm.set_perspective(90, 1, 0.01, radius); @@ -1996,7 +2008,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Vector<Plane> planes = cm.get_projection_planes(xform); - geometry_instances_to_shadow_render.clear(); instance_shadow_cull_result.clear(); Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size()); @@ -2015,7 +2026,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex); - Plane near_plane(xform.origin, -xform.basis.get_axis(2)); + RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { Instance *instance = instance_shadow_cull_result[j]; @@ -2030,22 +2041,28 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } } - geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); + shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); } RSG::storage->update_mesh_instances(); scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0); - scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render); + + shadow_data.light = light->instance; + shadow_data.pass = i; } //restore the regular DP matrix - scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); + //scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); } } break; case RS::LIGHT_SPOT: { RENDER_TIMESTAMP("Culling Spot Light"); + if (max_shadows_used + 1 > MAX_UPDATE_SHADOWS) { + return true; + } + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); @@ -2054,7 +2071,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons Vector<Plane> planes = cm.get_projection_planes(light_transform); - geometry_instances_to_shadow_render.clear(); instance_shadow_cull_result.clear(); Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size()); @@ -2073,7 +2089,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex); - Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2)); + RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++]; for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) { Instance *instance = instance_shadow_cull_result[j]; @@ -2088,13 +2104,14 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons RSG::storage->mesh_instance_check_for_update(instance->mesh_instance); } } - geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); + shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance); } RSG::storage->update_mesh_instances(); scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0); - scene_render->render_shadow(light->instance, p_shadow_atlas, 0, geometry_instances_to_shadow_render); + shadow_data.light = light->instance; + shadow_data.pass = 0; } break; } @@ -2147,14 +2164,13 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ RID environment = _render_get_environment(p_camera, p_scenario); - _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), p_screen_lod_threshold); - _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); + _render_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); #endif } void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) { // render for AR/VR interface - +#if 0 Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); @@ -2234,6 +2250,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_ // And render our scene... _render_scene(p_render_buffers, cam_transform, camera_matrix, false, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold); +#endif }; void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data) { @@ -2452,7 +2469,7 @@ void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullRes } } -void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows) { +void RendererSceneCull::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) { // Note, in stereo rendering: // - p_cam_transform will be a transform in the middle of our two eyes // - p_cam_projection is a wider frustrum that encompasses both eyes @@ -2466,6 +2483,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca scene_render->set_scene_pass(render_pass); if (p_render_buffers.is_valid()) { + //no rendering code here, this is only to set up what needs to be done, request regions, etc. scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not) } @@ -2596,62 +2614,28 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca //render shadows - for (uint32_t i = 0; i < cull.shadow_count; i++) { - for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) { - const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j]; - // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size())); - scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale); - scene_render->render_shadow(cull.shadows[i].light_instance, p_shadow_atlas, j, frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j], near_plane, p_cam_projection.get_lod_multiplier(), p_screen_lod_threshold); - } - } + max_shadows_used = 0; - //render SDFGI + if (p_using_shadows) { //setup shadow maps - { - if (cull.sdfgi.region_count > 0) { - //update regions - for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { - scene_render->render_sdfgi(p_render_buffers, i, frustum_cull_result.sdfgi_region_geometry_instances[i]); - } - //check if static lights were culled - bool static_lights_culled = false; - for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) { - if (frustum_cull_result.sdfgi_cascade_lights[i].size()) { - static_lights_culled = true; - break; - } - } + // Directional Shadows - if (static_lights_culled) { - scene_render->render_sdfgi_static_lights(p_render_buffers, cull.sdfgi.cascade_light_count, cull.sdfgi.cascade_light_index, frustum_cull_result.sdfgi_cascade_lights); + for (uint32_t i = 0; i < cull.shadow_count; i++) { + for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) { + const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j]; + // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size())); + scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale); + if (max_shadows_used == MAX_UPDATE_SHADOWS) { + continue; + } + render_shadow_data[max_shadows_used].light = cull.shadows[i].light_instance; + render_shadow_data[max_shadows_used].pass = j; + render_shadow_data[max_shadows_used].instances.merge_unordered(frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j]); + max_shadows_used++; } } - if (p_render_buffers.is_valid()) { - scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_lights, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size()); - } - } - - //light_samplers_culled=0; - - /* - print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0)); - print_line("OTO: "+itos(p_scenario->octree.get_octant_count())); - print_line("OTE: "+itos(p_scenario->octree.get_elem_count())); - print_line("OTP: "+itos(p_scenario->octree.get_pair_count())); - */ - - /* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */ - //removed, will replace with culling - - /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */ - - /* STEP 5 - PROCESS POSITIONAL LIGHTS */ - - if (p_using_shadows) { //setup shadow maps - - //SortArray<Instance*,_InstanceLightsort> sorter; - //sorter.sort(light_cull_result,light_cull_count); + // Positional Shadowss for (uint32_t i = 0; i < (uint32_t)frustum_cull_result.lights.size(); i++) { Instance *ins = frustum_cull_result.lights[i]; @@ -2738,19 +2722,78 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca bool redraw = scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version); - if (redraw) { + if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) { //must redraw! RENDER_TIMESTAMP(">Rendering Light " + itos(i)); light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario, p_screen_lod_threshold); RENDER_TIMESTAMP("<Rendering Light " + itos(i)); + } else { + light->shadow_dirty = redraw; } } } + //render SDFGI + + { + sdfgi_update_data.update_static = false; + + if (cull.sdfgi.region_count > 0) { + //update regions + for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { + render_sdfgi_data[i].instances.merge_unordered(frustum_cull_result.sdfgi_region_geometry_instances[i]); + render_sdfgi_data[i].region = i; + } + //check if static lights were culled + bool static_lights_culled = false; + for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) { + if (frustum_cull_result.sdfgi_cascade_lights[i].size()) { + static_lights_culled = true; + break; + } + } + + if (static_lights_culled) { + sdfgi_update_data.static_cascade_count = cull.sdfgi.cascade_light_count; + sdfgi_update_data.static_cascade_indices = cull.sdfgi.cascade_light_index; + sdfgi_update_data.static_positional_lights = frustum_cull_result.sdfgi_cascade_lights; + sdfgi_update_data.update_static = true; + } + } + + if (p_render_buffers.is_valid()) { + sdfgi_update_data.directional_lights = &directional_lights; + sdfgi_update_data.positional_light_instances = scenario->dynamic_lights.ptr(); + sdfgi_update_data.positional_light_count = scenario->dynamic_lights.size(); + } + } + //append the directional lights to the lights culled for (int i = 0; i < directional_lights.size(); i++) { frustum_cull_result.light_instances.push_back(directional_lights[i]); } + + RID camera_effects; + if (p_force_camera_effects.is_valid()) { + camera_effects = p_force_camera_effects; + } else { + camera_effects = scenario->camera_effects; + } + /* PROCESS GEOMETRY AND DRAW SCENE */ + + RENDER_TIMESTAMP("Render Scene "); + scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data); + + for (uint32_t i = 0; i < max_shadows_used; i++) { + render_shadow_data[i].instances.clear(); + } + max_shadows_used = 0; + + for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { + render_sdfgi_data[i].instances.clear(); + } + + // virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; } RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { @@ -2774,21 +2817,6 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { return RID(); } -void RendererSceneCull::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) { - Scenario *scenario = scenario_owner.getornull(p_scenario); - - RID camera_effects; - if (p_force_camera_effects.is_valid()) { - camera_effects = p_force_camera_effects; - } else { - camera_effects = scenario->camera_effects; - } - /* PROCESS GEOMETRY AND DRAW SCENE */ - - RENDER_TIMESTAMP("Render Scene "); - scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold); -} - void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { #ifndef _3D_DISABLED @@ -2801,7 +2829,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, environment = scenario->fallback_environment; } RENDER_TIMESTAMP("Render Empty Scene "); - scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0); + scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif } @@ -2864,8 +2892,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int } RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); - _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, lod_threshold, use_shadows); - _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold); + _render_scene(xform, cm, false, false, RID(), RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold, use_shadows); } else { //do roughness postprocess step until it believes it's done @@ -3493,7 +3520,12 @@ RendererSceneCull::RendererSceneCull() { instance_cull_result.set_page_pool(&instance_cull_page_pool); instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool); - geometry_instances_to_shadow_render.set_page_pool(&geometry_instance_cull_page_pool); + for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) { + render_shadow_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool); + } + for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + render_sdfgi_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool); + } frustum_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); frustum_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); @@ -3510,7 +3542,12 @@ RendererSceneCull::~RendererSceneCull() { instance_cull_result.reset(); instance_shadow_cull_result.reset(); - geometry_instances_to_shadow_render.reset(); + for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) { + render_shadow_data[i].instances.reset(); + } + for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { + render_sdfgi_data[i].instances.reset(); + } frustum_cull_result.reset(); for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 2ffaf48675..32f4334288 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -54,7 +54,8 @@ public: enum { SDFGI_MAX_CASCADES = 8, SDFGI_MAX_REGIONS_PER_CASCADE = 3, - MAX_INSTANCE_PAIRS = 32 + MAX_INSTANCE_PAIRS = 32, + MAX_UPDATE_SHADOWS = 512 }; uint64_t render_pass; @@ -93,9 +94,11 @@ public: } }; - mutable RID_PtrOwner<Camera> camera_owner; + mutable RID_PtrOwner<Camera, true> camera_owner; + + virtual RID camera_allocate(); + virtual void camera_initialize(RID p_rid); - virtual RID camera_create(); virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far); virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far); @@ -295,14 +298,15 @@ public: int indexer_update_iterations = 0; - mutable RID_PtrOwner<Scenario> scenario_owner; + mutable RID_PtrOwner<Scenario, true> scenario_owner; static void _instance_pair(Instance *p_A, Instance *p_B); static void _instance_unpair(Instance *p_A, Instance *p_B); void _instance_update_mesh_instance(Instance *p_instance); - virtual RID scenario_create(); + virtual RID scenario_allocate(); + virtual void scenario_initialize(RID p_rid); virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode); virtual void scenario_set_environment(RID p_scenario, RID p_environment); @@ -696,7 +700,6 @@ public: PagedArray<Instance *> instance_cull_result; PagedArray<Instance *> instance_shadow_cull_result; - PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances_to_shadow_render; struct FrustumCullResult { PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances; @@ -816,13 +819,20 @@ public: FrustumCullResult frustum_cull_result; LocalVector<FrustumCullResult> frustum_cull_result_threads; + RendererSceneRender::RenderShadowData render_shadow_data[MAX_UPDATE_SHADOWS]; + uint32_t max_shadows_used = 0; + + RendererSceneRender::RenderSDFGIData render_sdfgi_data[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; + RendererSceneRender::RenderSDFGIUpdateData sdfgi_update_data; + uint32_t thread_cull_threshold = 200; - RID_PtrOwner<Instance> instance_owner; + RID_PtrOwner<Instance, true> instance_owner; uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered - virtual RID instance_create(); + virtual RID instance_allocate(); + virtual void instance_initialize(RID p_rid); virtual void instance_set_base(RID p_instance, RID p_base); virtual void instance_set_scenario(RID p_instance, RID p_scenario); @@ -924,8 +934,7 @@ public: void _frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to); bool _render_reflection_probe_step(Instance *p_instance, int p_step); - void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows = true); - void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold); + void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true); void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas); void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas); @@ -952,13 +961,16 @@ public: /* SKY API */ - PASS0R(RID, sky_create) + PASS0R(RID, sky_allocate) + PASS1(sky_initialize, RID) + PASS2(sky_set_radiance_size, RID, int) PASS2(sky_set_mode, RID, RS::SkyMode) PASS2(sky_set_material, RID, RID) PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) - PASS0R(RID, environment_create) + PASS0R(RID, environment_allocate) + PASS1(environment_initialize, RID) PASS1RC(bool, is_environment, RID) @@ -986,14 +998,12 @@ public: PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - PASS9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter) + PASS10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) PASS2(environment_set_volumetric_fog_volume_size, int, int) PASS1(environment_set_volumetric_fog_filter_active, bool) - PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) - PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) + PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float) PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount) PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge) PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight) @@ -1009,7 +1019,8 @@ public: /* CAMERA EFFECTS */ - PASS0R(RID, camera_effects_create) + PASS0R(RID, camera_effects_allocate) + PASS1(camera_effects_initialize, RID) PASS2(camera_effects_set_dof_blur_quality, RS::DOFBlurQuality, bool) PASS1(camera_effects_set_dof_blur_bokeh_shape, RS::DOFBokehShape) diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index ecec03db94..1dea3580b6 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -71,8 +71,7 @@ public: /* SHADOW ATLAS API */ - virtual RID - shadow_atlas_create() = 0; + virtual RID shadow_atlas_create() = 0; virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0; @@ -87,11 +86,12 @@ public: virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0; virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0; virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0; - virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const Vector<RID> &p_directional_lights, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0; /* SKY API */ - virtual RID sky_create() = 0; + virtual RID sky_allocate() = 0; + virtual void sky_initialize(RID p_rid) = 0; + virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; @@ -99,7 +99,8 @@ public: /* ENVIRONMENT API */ - virtual RID environment_create() = 0; + virtual RID environment_allocate() = 0; + virtual void environment_initialize(RID p_rid) = 0; virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0; virtual void environment_set_sky(RID p_env, RID p_sky) = 0; @@ -118,12 +119,9 @@ public: virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; - + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; @@ -132,7 +130,7 @@ public: virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0; @@ -150,7 +148,8 @@ public: virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; virtual int environment_get_canvas_max_layer(RID p_env) const = 0; - virtual RID camera_effects_create() = 0; + virtual RID camera_effects_allocate() = 0; + virtual void camera_effects_initialize(RID p_rid) = 0; virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0; virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0; @@ -195,12 +194,31 @@ public: virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0; - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0; + struct RenderShadowData { + RID light; + int pass = 0; + PagedArray<GeometryInstance *> instances; + }; + + struct RenderSDFGIData { + int region = 0; + PagedArray<GeometryInstance *> instances; + }; + + struct RenderSDFGIUpdateData { + bool update_static = false; + uint32_t static_cascade_count; + uint32_t *static_cascade_indices; + PagedArray<RID> *static_positional_lights; + + const Vector<RID> *directional_lights; + const RID *positional_light_instances; + uint32_t positional_light_count; + }; + + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) = 0; - virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0; virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) = 0; - virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0; virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; virtual void set_scene_pass(uint64_t p_pass) = 0; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 7a80c2b0bf..69ad2cc191 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -98,6 +98,7 @@ public: while (to_clean_up.size()) { to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second); + dependencies.erase(to_clean_up.front()->get().first); to_clean_up.pop_front(); } } @@ -118,12 +119,15 @@ public: Set<Dependency *> dependencies; }; + virtual bool can_create_resources_async() const = 0; /* TEXTURE API */ - virtual RID texture_2d_create(const Ref<Image> &p_image) = 0; - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; - virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent + virtual RID texture_allocate() = 0; + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) = 0; + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; + virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; + virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; @@ -131,9 +135,9 @@ public: virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; //these two APIs can be used together or in combination with the others. - virtual RID texture_2d_placeholder_create() = 0; - virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0; - virtual RID texture_3d_placeholder_create() = 0; + virtual void texture_2d_placeholder_initialize(RID p_texture) = 0; + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) = 0; + virtual void texture_3d_placeholder_initialize(RID p_texture) = 0; virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; @@ -160,7 +164,9 @@ public: /* CANVAS TEXTURE API */ - virtual RID canvas_texture_create() = 0; + virtual RID canvas_texture_allocate() = 0; + virtual void canvas_texture_initialize(RID p_rid) = 0; + virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0; virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0; @@ -169,7 +175,8 @@ public: /* SHADER API */ - virtual RID shader_create() = 0; + virtual RID shader_allocate() = 0; + virtual void shader_initialize(RID p_rid) = 0; virtual void shader_set_code(RID p_shader, const String &p_code) = 0; virtual String shader_get_code(RID p_shader) const = 0; @@ -183,7 +190,8 @@ public: /* COMMON MATERIAL API */ - virtual RID material_create() = 0; + virtual RID material_allocate() = 0; + virtual void material_initialize(RID p_rid) = 0; virtual void material_set_render_priority(RID p_material, int priority) = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; @@ -208,7 +216,8 @@ public: /* MESH API */ - virtual RID mesh_create() = 0; + virtual RID mesh_allocate() = 0; + virtual void mesh_initialize(RID p_rid) = 0; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) = 0; @@ -250,9 +259,10 @@ public: /* MULTIMESH API */ - virtual RID multimesh_create() = 0; + virtual RID multimesh_allocate() = 0; + virtual void multimesh_initialize(RID p_rid) = 0; - virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; + virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; @@ -279,7 +289,9 @@ public: /* IMMEDIATE API */ - virtual RID immediate_create() = 0; + virtual RID immediate_allocate() = 0; + virtual void immediate_initialize(RID p_rid) = 0; + virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0; virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0; virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0; @@ -295,8 +307,10 @@ public: /* SKELETON API */ - virtual RID skeleton_create() = 0; - virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; + virtual RID skeleton_allocate() = 0; + virtual void skeleton_initialize(RID p_rid) = 0; + + virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; @@ -306,11 +320,14 @@ public: /* Light API */ - virtual RID light_create(RS::LightType p_type) = 0; + virtual RID directional_light_allocate() = 0; + virtual void directional_light_initialize(RID p_rid) = 0; - RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); } - RID omni_light_create() { return light_create(RS::LIGHT_OMNI); } - RID spot_light_create() { return light_create(RS::LIGHT_SPOT); } + virtual RID omni_light_allocate() = 0; + virtual void omni_light_initialize(RID p_rid) = 0; + + virtual RID spot_light_allocate() = 0; + virtual void spot_light_initialize(RID p_rid) = 0; virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; @@ -348,7 +365,8 @@ public: /* PROBE API */ - virtual RID reflection_probe_create() = 0; + virtual RID reflection_probe_allocate() = 0; + virtual void reflection_probe_initialize(RID p_rid) = 0; virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0; virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0; @@ -379,7 +397,9 @@ public: /* DECAL API */ - virtual RID decal_create() = 0; + virtual RID decal_allocate() = 0; + virtual void decal_initialize(RID p_rid) = 0; + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0; virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0; virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0; @@ -394,9 +414,10 @@ public: /* GI PROBE API */ - virtual RID gi_probe_create() = 0; + virtual RID gi_probe_allocate() = 0; + virtual void gi_probe_initialize(RID p_rid) = 0; - virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; @@ -439,9 +460,10 @@ public: virtual uint32_t gi_probe_get_version(RID p_probe) = 0; - /* LIGHTMAP CAPTURE */ + /* LIGHTMAP */ - virtual RID lightmap_create() = 0; + virtual RID lightmap_allocate() = 0; + virtual void lightmap_initialize(RID p_rid) = 0; virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; @@ -459,7 +481,8 @@ public: /* PARTICLES */ - virtual RID particles_create() = 0; + virtual RID particles_allocate() = 0; + virtual void particles_initialize(RID p_rid) = 0; virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; virtual bool particles_get_emitting(RID p_particles) = 0; @@ -506,7 +529,9 @@ public: /* PARTICLES COLLISION */ - virtual RID particles_collision_create() = 0; + virtual RID particles_collision_allocate() = 0; + virtual void particles_collision_initialize(RID p_rid) = 0; + virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0; virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0; virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index d52da5b331..fc3d8a78e7 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -608,19 +608,20 @@ void RendererViewport::draw_viewports() { } } -RID RendererViewport::viewport_create() { - Viewport *viewport = memnew(Viewport); - - RID rid = viewport_owner.make_rid(viewport); +RID RendererViewport::viewport_allocate() { + return viewport_owner.allocate_rid(); +} - viewport->self = rid; +void RendererViewport::viewport_initialize(RID p_rid) { + Viewport *viewport = memnew(Viewport); + viewport->self = p_rid; viewport->hide_scenario = false; viewport->hide_canvas = false; viewport->render_target = RSG::storage->render_target_create(); viewport->shadow_atlas = RSG::scene->shadow_atlas_create(); viewport->viewport_render_direct_to_screen = false; - return rid; + viewport_owner.initialize_rid(p_rid, viewport); } void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { @@ -1019,5 +1020,10 @@ void RendererViewport::set_default_clear_color(const Color &p_color) { RSG::storage->set_default_clear_color(p_color); } +//workaround for setting this on thread +void RendererViewport::call_set_use_vsync(bool p_enable) { + DisplayServer::get_singleton()->_set_use_vsync(p_enable); +} + RendererViewport::RendererViewport() { } diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index 979cbb095b..f5ed543e8d 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -165,7 +165,7 @@ public: uint64_t draw_viewports_pass = 0; - mutable RID_PtrOwner<Viewport> viewport_owner; + mutable RID_PtrOwner<Viewport, true> viewport_owner; struct ViewportSort { _FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const { @@ -186,7 +186,8 @@ private: void _draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye = XRInterface::EYE_MONO); public: - RID viewport_create(); + RID viewport_allocate(); + void viewport_initialize(RID p_rid); void viewport_set_use_xr(RID p_viewport, bool p_use_xr); @@ -249,6 +250,9 @@ public: bool free(RID p_rid); + //workaround for setting this on thread + void call_set_use_vsync(bool p_enable); + RendererViewport(); virtual ~RendererViewport() {} }; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 70497bcdb3..4b0eafe369 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -240,10 +240,6 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); } -void RenderingDevice::compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads, uint32_t p_x_local_group, uint32_t p_y_local_group, uint32_t p_z_local_group) { - compute_list_dispatch(p_list, (p_x_threads - 1) / p_x_local_group + 1, (p_y_threads - 1) / p_y_local_group + 1, (p_z_threads - 1) / p_z_local_group + 1); -} - void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); @@ -319,7 +315,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL)); - ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin); + ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant); ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); @@ -352,10 +348,15 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_command_insert_label", "name", "color"), &RenderingDevice::draw_command_insert_label); ClassDB::bind_method(D_METHOD("draw_command_end_label"), &RenderingDevice::draw_command_end_label); + ClassDB::bind_method(D_METHOD("get_device_vendor_name"), &RenderingDevice::get_device_vendor_name); + ClassDB::bind_method(D_METHOD("get_device_name"), &RenderingDevice::get_device_name); + ClassDB::bind_method(D_METHOD("get_device_pipeline_cache_uuid"), &RenderingDevice::get_device_pipeline_cache_uuid); + BIND_CONSTANT(BARRIER_MASK_RASTER); BIND_CONSTANT(BARRIER_MASK_COMPUTE); BIND_CONSTANT(BARRIER_MASK_TRANSFER); BIND_CONSTANT(BARRIER_MASK_ALL); + BIND_CONSTANT(BARRIER_MASK_NO_BARRIER); BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8); BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16); @@ -760,6 +761,7 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION_CONTINUE); //continue rendering and clear the framebuffer (supply params) BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 47ef54cef7..9fbf58d131 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -343,6 +343,7 @@ public: BARRIER_MASK_RASTER = 1, BARRIER_MASK_COMPUTE = 2, BARRIER_MASK_TRANSFER = 4, + BARRIER_MASK_NO_BARRIER = 8, BARRIER_MASK_ALL = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER }; @@ -944,6 +945,7 @@ public: enum InitialAction { INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params) INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params) + INITIAL_ACTION_CLEAR_REGION_CONTINUE, //countinue rendering and clear the framebuffer in the specified region (supply params) INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared) INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously) @@ -983,12 +985,12 @@ public: typedef int64_t ComputeListID; - virtual ComputeListID compute_list_begin() = 0; + virtual ComputeListID compute_list_begin(bool p_allow_draw_overlap = false) = 0; virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0; virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0; virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; - virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads, uint32_t p_x_local_group, uint32_t p_y_local_group, uint32_t p_z_local_group); + virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads) = 0; virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; @@ -1078,6 +1080,10 @@ public: virtual void draw_command_insert_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)) = 0; virtual void draw_command_end_label() = 0; + virtual String get_device_vendor_name() const = 0; + virtual String get_device_name() const = 0; + virtual String get_device_pipeline_cache_uuid() const = 0; + static RenderingDevice *get_singleton(); RenderingDevice(); diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 360b333454..2e8f60d879 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -64,7 +64,7 @@ void RenderingServerDefault::_draw_margins() { /* FREE */ -void RenderingServerDefault::free(RID p_rid) { +void RenderingServerDefault::_free(RID p_rid) { if (RSG::storage->free(p_rid)) { return; } @@ -91,7 +91,7 @@ void RenderingServerDefault::request_frame_drawn_callback(Object *p_where, const frame_drawn_callbacks.push_back(fdc); } -void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) { +void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { //needs to be done before changes is reset to 0, to not force the editor to redraw RS::get_singleton()->emit_signal("frame_pre_draw"); @@ -213,18 +213,15 @@ float RenderingServerDefault::get_frame_setup_time_cpu() const { return frame_setup_time; } -void RenderingServerDefault::sync() { -} - bool RenderingServerDefault::has_changed() const { return changes > 0; } -void RenderingServerDefault::init() { +void RenderingServerDefault::_init() { RSG::rasterizer->initialize(); } -void RenderingServerDefault::finish() { +void RenderingServerDefault::_finish() { if (test_cube.is_valid()) { free(test_cube); } @@ -232,6 +229,32 @@ void RenderingServerDefault::finish() { RSG::rasterizer->finalize(); } +void RenderingServerDefault::init() { + if (create_thread) { + print_verbose("RenderingServerWrapMT: Creating render thread"); + DisplayServer::get_singleton()->release_rendering_thread(); + if (create_thread) { + thread.start(_thread_callback, this); + print_verbose("RenderingServerWrapMT: Starting render thread"); + } + while (!draw_thread_up) { + OS::get_singleton()->delay_usec(1000); + } + print_verbose("RenderingServerWrapMT: Finished render thread"); + } else { + _init(); + } +} + +void RenderingServerDefault::finish() { + if (create_thread) { + command_queue.push(this, &RenderingServerDefault::_thread_exit); + thread.wait_to_finish(); + } else { + _finish(); + } +} + /* STATUS INFORMATION */ int RenderingServerDefault::get_render_info(RenderInfo p_info) { @@ -297,10 +320,6 @@ void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) { RSG::storage->set_debug_generate_wireframes(p_generate); } -void RenderingServerDefault::call_set_use_vsync(bool p_enable) { - DisplayServer::get_singleton()->_set_use_vsync(p_enable); -} - bool RenderingServerDefault::is_low_end() const { // FIXME: Commented out when rebasing vulkan branch on master, // causes a crash, it seems rasterizer is not initialized yet the @@ -309,7 +328,77 @@ bool RenderingServerDefault::is_low_end() const { return false; } -RenderingServerDefault::RenderingServerDefault() { +void RenderingServerDefault::_thread_exit() { + exit = true; +} + +void RenderingServerDefault::_thread_draw(bool p_swap_buffers, double frame_step) { + if (!atomic_decrement(&draw_pending)) { + _draw(p_swap_buffers, frame_step); + } +} + +void RenderingServerDefault::_thread_flush() { + atomic_decrement(&draw_pending); +} + +void RenderingServerDefault::_thread_callback(void *_instance) { + RenderingServerDefault *vsmt = reinterpret_cast<RenderingServerDefault *>(_instance); + + vsmt->_thread_loop(); +} + +void RenderingServerDefault::_thread_loop() { + server_thread = Thread::get_caller_id(); + + DisplayServer::get_singleton()->make_rendering_thread(); + + _init(); + + exit = false; + draw_thread_up = true; + while (!exit) { + // flush commands one by one, until exit is requested + command_queue.wait_and_flush_one(); + } + + command_queue.flush_all(); // flush all + + _finish(); +} + +/* EVENT QUEUING */ + +void RenderingServerDefault::sync() { + if (create_thread) { + atomic_increment(&draw_pending); + command_queue.push_and_sync(this, &RenderingServerDefault::_thread_flush); + } else { + command_queue.flush_all(); //flush all pending from other threads + } +} + +void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) { + if (create_thread) { + atomic_increment(&draw_pending); + command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step); + } else { + _draw(p_swap_buffers, frame_step); + } +} + +RenderingServerDefault::RenderingServerDefault(bool p_create_thread) : + command_queue(p_create_thread) { + create_thread = p_create_thread; + draw_pending = 0; + draw_thread_up = false; + + if (!p_create_thread) { + server_thread = Thread::get_caller_id(); + } else { + server_thread = 0; + } + RSG::canvas = memnew(RendererCanvasCull); RSG::viewport = memnew(RendererViewport); RendererSceneCull *sr = memnew(RendererSceneCull); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 83afd9096d..effa555ec4 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -32,6 +32,7 @@ #define RENDERING_SERVER_DEFAULT_H #include "core/math/octree.h" +#include "core/templates/command_queue_mt.h" #include "core/templates/ordered_hash_map.h" #include "renderer_canvas_cull.h" #include "renderer_scene_cull.h" @@ -39,6 +40,7 @@ #include "rendering_server_globals.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering_server.h" +#include "servers/server_wrap_mt_common.h" class RenderingServerDefault : public RenderingServer { enum { @@ -81,6 +83,31 @@ class RenderingServerDefault : public RenderingServer { uint64_t print_frame_profile_ticks_from = 0; uint32_t print_frame_profile_frame_count = 0; + mutable CommandQueueMT command_queue; + + static void _thread_callback(void *_instance); + void _thread_loop(); + + Thread::ID server_thread; + volatile bool exit; + Thread thread; + volatile bool draw_thread_up; + bool create_thread; + + uint64_t draw_pending; + void _thread_draw(bool p_swap_buffers, double frame_step); + void _thread_flush(); + + void _thread_exit(); + + Mutex alloc_mutex; + + void _draw(bool p_swap_buffers, double frame_step); + void _init(); + void _finish(); + + void _free(RID p_rid); + public: //if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() //#define DEBUG_CHANGES @@ -97,809 +124,813 @@ public: #else _FORCE_INLINE_ static void redraw_request() { changes++; } +#endif -#define DISPLAY_CHANGED \ - changes++; +#define WRITE_ACTION redraw_request(); + +#ifdef DEBUG_SYNC +#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); +#else +#define SYNC_DEBUG #endif -#define BIND0R(m_r, m_name) \ - m_r m_name() { return BINDBASE->m_name(); } -#define BIND0RC(m_r, m_name) \ - m_r m_name() const { return BINDBASE->m_name(); } -#define BIND1R(m_r, m_name, m_type1) \ - m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); } -#define BIND1RC(m_r, m_name, m_type1) \ - m_r m_name(m_type1 arg1) const { return BINDBASE->m_name(arg1); } -#define BIND2R(m_r, m_name, m_type1, m_type2) \ - m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); } -#define BIND2RC(m_r, m_name, m_type1, m_type2) \ - m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); } -#define BIND3R(m_r, m_name, m_type1, m_type2, m_type3) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return BINDBASE->m_name(arg1, arg2, arg3); } -#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return BINDBASE->m_name(arg1, arg2, arg3); } -#define BIND4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } -#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } -#define BIND5R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } -#define BIND5RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } -#define BIND6R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } -#define BIND6RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } - -#define BIND0(m_name) \ - void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); } -#define BIND1(m_name, m_type1) \ - void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); } -#define BIND1C(m_name, m_type1) \ - void m_name(m_type1 arg1) const { DISPLAY_CHANGED BINDBASE->m_name(arg1); } -#define BIND2(m_name, m_type1, m_type2) \ - void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); } -#define BIND2C(m_name, m_type1, m_type2) \ - void m_name(m_type1 arg1, m_type2 arg2) const { BINDBASE->m_name(arg1, arg2); } -#define BIND3(m_name, m_type1, m_type2, m_type3) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3); } -#define BIND4(m_name, m_type1, m_type2, m_type3, m_type4) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4); } -#define BIND5(m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); } -#define BIND6(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); } -#define BIND7(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } -#define BIND8(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } -#define BIND9(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); } -#define BIND10(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); } -#define BIND11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); } -#define BIND12(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); } -#define BIND13(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); } -#define BIND14(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); } -#define BIND15(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14, m_type15) \ - void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14, m_type15 arg15) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); } +#include "servers/server_wrap_mt_common.h" //from now on, calls forwarded to this singleton -#define BINDBASE RSG::storage +#define ServerName RendererStorage +#define server_name RSG::storage /* TEXTURE API */ +#define FUNCRIDTEX0(m_type) \ + virtual RID m_type##_create() override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret); \ + } \ + return ret; \ + } + +#define FUNCRIDTEX1(m_type, m_type1) \ + virtual RID m_type##_create(m_type1 p1) override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret, p1); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1); \ + } \ + return ret; \ + } + +#define FUNCRIDTEX2(m_type, m_type1, m_type2) \ + virtual RID m_type##_create(m_type1 p1, m_type2 p2) override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret, p1, p2); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2); \ + } \ + return ret; \ + } + +#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \ + RID ret = RSG::storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ + RSG::storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6); \ + } \ + return ret; \ + } + //these go pass-through, as they can be called from any thread - BIND1R(RID, texture_2d_create, const Ref<Image> &) - BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image>> &, TextureLayeredType) - BIND6R(RID, texture_3d_create, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &) - BIND1R(RID, texture_proxy_create, RID) + FUNCRIDTEX1(texture_2d, const Ref<Image> &) + FUNCRIDTEX2(texture_2d_layered, const Vector<Ref<Image>> &, TextureLayeredType) + FUNCRIDTEX6(texture_3d, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &) + FUNCRIDTEX1(texture_proxy, RID) //goes pass-through - BIND3(texture_2d_update_immediate, RID, const Ref<Image> &, int) + FUNC3(texture_2d_update_immediate, RID, const Ref<Image> &, int) //these go through command queue if they are in another thread - BIND3(texture_2d_update, RID, const Ref<Image> &, int) - BIND2(texture_3d_update, RID, const Vector<Ref<Image>> &) - BIND2(texture_proxy_update, RID, RID) + FUNC3(texture_2d_update, RID, const Ref<Image> &, int) + FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &) + FUNC2(texture_proxy_update, RID, RID) //these also go pass-through - BIND0R(RID, texture_2d_placeholder_create) - BIND1R(RID, texture_2d_layered_placeholder_create, TextureLayeredType) - BIND0R(RID, texture_3d_placeholder_create) + FUNCRIDTEX0(texture_2d_placeholder) + FUNCRIDTEX1(texture_2d_layered_placeholder, TextureLayeredType) + FUNCRIDTEX0(texture_3d_placeholder) - BIND1RC(Ref<Image>, texture_2d_get, RID) - BIND2RC(Ref<Image>, texture_2d_layer_get, RID, int) - BIND1RC(Vector<Ref<Image>>, texture_3d_get, RID) + FUNC1RC(Ref<Image>, texture_2d_get, RID) + FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int) + FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID) - BIND2(texture_replace, RID, RID) + FUNC2(texture_replace, RID, RID) - BIND3(texture_set_size_override, RID, int, int) + FUNC3(texture_set_size_override, RID, int, int) // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 - BIND2(texture_bind, RID, uint32_t) + FUNC2(texture_bind, RID, uint32_t) #endif - BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) - BIND3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) - BIND3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *) + FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) + FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) + FUNC3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *) - BIND2(texture_set_path, RID, const String &) - BIND1RC(String, texture_get_path, RID) - BIND1(texture_debug_usage, List<TextureInfo> *) + FUNC2(texture_set_path, RID, const String &) + FUNC1RC(String, texture_get_path, RID) + FUNC1(texture_debug_usage, List<TextureInfo> *) - BIND2(texture_set_force_redraw_if_visible, RID, bool) + FUNC2(texture_set_force_redraw_if_visible, RID, bool) /* SHADER API */ - BIND0R(RID, shader_create) + FUNCRIDSPLIT(shader) - BIND2(shader_set_code, RID, const String &) - BIND1RC(String, shader_get_code, RID) + FUNC2(shader_set_code, RID, const String &) + FUNC1RC(String, shader_get_code, RID) - BIND2C(shader_get_param_list, RID, List<PropertyInfo> *) + FUNC2C(shader_get_param_list, RID, List<PropertyInfo> *) - BIND3(shader_set_default_texture_param, RID, const StringName &, RID) - BIND2RC(RID, shader_get_default_texture_param, RID, const StringName &) - BIND2RC(Variant, shader_get_param_default, RID, const StringName &) + FUNC3(shader_set_default_texture_param, RID, const StringName &, RID) + FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &) + FUNC2RC(Variant, shader_get_param_default, RID, const StringName &) - BIND1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) + FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) /* COMMON MATERIAL API */ - BIND0R(RID, material_create) + FUNCRIDSPLIT(material) - BIND2(material_set_shader, RID, RID) + FUNC2(material_set_shader, RID, RID) - BIND3(material_set_param, RID, const StringName &, const Variant &) - BIND2RC(Variant, material_get_param, RID, const StringName &) + FUNC3(material_set_param, RID, const StringName &, const Variant &) + FUNC2RC(Variant, material_get_param, RID, const StringName &) - BIND2(material_set_render_priority, RID, int) - BIND2(material_set_next_pass, RID, RID) + FUNC2(material_set_render_priority, RID, int) + FUNC2(material_set_next_pass, RID, RID) /* MESH API */ - virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) { - RID mesh = mesh_create(); - mesh_set_blend_shape_count(mesh, p_blend_shape_count); - for (int i = 0; i < p_surfaces.size(); i++) { - mesh_add_surface(mesh, p_surfaces[i]); + virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) override { + RID mesh = RSG::storage->mesh_allocate(); + + if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { + if (Thread::get_caller_id() == server_thread) { + command_queue.flush_if_pending(); + } + RSG::storage->mesh_initialize(mesh); + RSG::storage->mesh_set_blend_shape_count(mesh, p_blend_shape_count); + for (int i = 0; i < p_surfaces.size(); i++) { + RSG::storage->mesh_add_surface(mesh, p_surfaces[i]); + } + } else { + command_queue.push(RSG::storage, &RendererStorage::mesh_initialize, mesh); + command_queue.push(RSG::storage, &RendererStorage::mesh_set_blend_shape_count, mesh, p_blend_shape_count); + for (int i = 0; i < p_surfaces.size(); i++) { + RSG::storage->mesh_add_surface(mesh, p_surfaces[i]); + command_queue.push(RSG::storage, &RendererStorage::mesh_add_surface, mesh, p_surfaces[i]); + } } + return mesh; } - BIND2(mesh_set_blend_shape_count, RID, int) + FUNC2(mesh_set_blend_shape_count, RID, int) - BIND0R(RID, mesh_create) + FUNCRIDSPLIT(mesh) - BIND2(mesh_add_surface, RID, const SurfaceData &) + FUNC2(mesh_add_surface, RID, const SurfaceData &) - BIND1RC(int, mesh_get_blend_shape_count, RID) + FUNC1RC(int, mesh_get_blend_shape_count, RID) - BIND2(mesh_set_blend_shape_mode, RID, BlendShapeMode) - BIND1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) + FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) + FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) - BIND4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) + FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) - BIND3(mesh_surface_set_material, RID, int, RID) - BIND2RC(RID, mesh_surface_get_material, RID, int) + FUNC3(mesh_surface_set_material, RID, int, RID) + FUNC2RC(RID, mesh_surface_get_material, RID, int) - BIND2RC(SurfaceData, mesh_get_surface, RID, int) + FUNC2RC(SurfaceData, mesh_get_surface, RID, int) - BIND1RC(int, mesh_get_surface_count, RID) + FUNC1RC(int, mesh_get_surface_count, RID) - BIND2(mesh_set_custom_aabb, RID, const AABB &) - BIND1RC(AABB, mesh_get_custom_aabb, RID) + FUNC2(mesh_set_custom_aabb, RID, const AABB &) + FUNC1RC(AABB, mesh_get_custom_aabb, RID) - BIND2(mesh_set_shadow_mesh, RID, RID) + FUNC2(mesh_set_shadow_mesh, RID, RID) - BIND1(mesh_clear, RID) + FUNC1(mesh_clear, RID) /* MULTIMESH API */ - BIND0R(RID, multimesh_create) + FUNCRIDSPLIT(multimesh) - BIND5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool) - BIND1RC(int, multimesh_get_instance_count, RID) + FUNC5(multimesh_allocate_data, RID, int, MultimeshTransformFormat, bool, bool) + FUNC1RC(int, multimesh_get_instance_count, RID) - BIND2(multimesh_set_mesh, RID, RID) - BIND3(multimesh_instance_set_transform, RID, int, const Transform &) - BIND3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) - BIND3(multimesh_instance_set_color, RID, int, const Color &) - BIND3(multimesh_instance_set_custom_data, RID, int, const Color &) + FUNC2(multimesh_set_mesh, RID, RID) + FUNC3(multimesh_instance_set_transform, RID, int, const Transform &) + FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) + FUNC3(multimesh_instance_set_color, RID, int, const Color &) + FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &) - BIND1RC(RID, multimesh_get_mesh, RID) - BIND1RC(AABB, multimesh_get_aabb, RID) + FUNC1RC(RID, multimesh_get_mesh, RID) + FUNC1RC(AABB, multimesh_get_aabb, RID) - BIND2RC(Transform, multimesh_instance_get_transform, RID, int) - BIND2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) - BIND2RC(Color, multimesh_instance_get_color, RID, int) - BIND2RC(Color, multimesh_instance_get_custom_data, RID, int) + FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) + FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) + FUNC2RC(Color, multimesh_instance_get_color, RID, int) + FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int) - BIND2(multimesh_set_buffer, RID, const Vector<float> &) - BIND1RC(Vector<float>, multimesh_get_buffer, RID) + FUNC2(multimesh_set_buffer, RID, const Vector<float> &) + FUNC1RC(Vector<float>, multimesh_get_buffer, RID) - BIND2(multimesh_set_visible_instances, RID, int) - BIND1RC(int, multimesh_get_visible_instances, RID) + FUNC2(multimesh_set_visible_instances, RID, int) + FUNC1RC(int, multimesh_get_visible_instances, RID) /* IMMEDIATE API */ - BIND0R(RID, immediate_create) - BIND3(immediate_begin, RID, PrimitiveType, RID) - BIND2(immediate_vertex, RID, const Vector3 &) - BIND2(immediate_normal, RID, const Vector3 &) - BIND2(immediate_tangent, RID, const Plane &) - BIND2(immediate_color, RID, const Color &) - BIND2(immediate_uv, RID, const Vector2 &) - BIND2(immediate_uv2, RID, const Vector2 &) - BIND1(immediate_end, RID) - BIND1(immediate_clear, RID) - BIND2(immediate_set_material, RID, RID) - BIND1RC(RID, immediate_get_material, RID) + FUNCRIDSPLIT(immediate) + FUNC3(immediate_begin, RID, PrimitiveType, RID) + FUNC2(immediate_vertex, RID, const Vector3 &) + FUNC2(immediate_normal, RID, const Vector3 &) + FUNC2(immediate_tangent, RID, const Plane &) + FUNC2(immediate_color, RID, const Color &) + FUNC2(immediate_uv, RID, const Vector2 &) + FUNC2(immediate_uv2, RID, const Vector2 &) + FUNC1(immediate_end, RID) + FUNC1(immediate_clear, RID) + FUNC2(immediate_set_material, RID, RID) + FUNC1RC(RID, immediate_get_material, RID) /* SKELETON API */ - BIND0R(RID, skeleton_create) - BIND3(skeleton_allocate, RID, int, bool) - BIND1RC(int, skeleton_get_bone_count, RID) - BIND3(skeleton_bone_set_transform, RID, int, const Transform &) - BIND2RC(Transform, skeleton_bone_get_transform, RID, int) - BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) - BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) - BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &) + FUNCRIDSPLIT(skeleton) + FUNC3(skeleton_allocate_data, RID, int, bool) + FUNC1RC(int, skeleton_get_bone_count, RID) + FUNC3(skeleton_bone_set_transform, RID, int, const Transform &) + FUNC2RC(Transform, skeleton_bone_get_transform, RID, int) + FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) + FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) + FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &) /* Light API */ - BIND0R(RID, directional_light_create) - BIND0R(RID, omni_light_create) - BIND0R(RID, spot_light_create) + FUNCRIDSPLIT(directional_light) + FUNCRIDSPLIT(omni_light) + FUNCRIDSPLIT(spot_light) - BIND2(light_set_color, RID, const Color &) - BIND3(light_set_param, RID, LightParam, float) - BIND2(light_set_shadow, RID, bool) - BIND2(light_set_shadow_color, RID, const Color &) - BIND2(light_set_projector, RID, RID) - BIND2(light_set_negative, RID, bool) - BIND2(light_set_cull_mask, RID, uint32_t) - BIND2(light_set_reverse_cull_face_mode, RID, bool) - BIND2(light_set_bake_mode, RID, LightBakeMode) - BIND2(light_set_max_sdfgi_cascade, RID, uint32_t) + FUNC2(light_set_color, RID, const Color &) + FUNC3(light_set_param, RID, LightParam, float) + FUNC2(light_set_shadow, RID, bool) + FUNC2(light_set_shadow_color, RID, const Color &) + FUNC2(light_set_projector, RID, RID) + FUNC2(light_set_negative, RID, bool) + FUNC2(light_set_cull_mask, RID, uint32_t) + FUNC2(light_set_reverse_cull_face_mode, RID, bool) + FUNC2(light_set_bake_mode, RID, LightBakeMode) + FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t) - BIND2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) + FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) - BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) - BIND2(light_directional_set_blend_splits, RID, bool) - BIND2(light_directional_set_sky_only, RID, bool) - BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) + FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) + FUNC2(light_directional_set_blend_splits, RID, bool) + FUNC2(light_directional_set_sky_only, RID, bool) + FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) /* PROBE API */ - BIND0R(RID, reflection_probe_create) - - BIND2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) - BIND2(reflection_probe_set_intensity, RID, float) - BIND2(reflection_probe_set_ambient_color, RID, const Color &) - BIND2(reflection_probe_set_ambient_energy, RID, float) - BIND2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode) - BIND2(reflection_probe_set_max_distance, RID, float) - BIND2(reflection_probe_set_extents, RID, const Vector3 &) - BIND2(reflection_probe_set_origin_offset, RID, const Vector3 &) - BIND2(reflection_probe_set_as_interior, RID, bool) - BIND2(reflection_probe_set_enable_box_projection, RID, bool) - BIND2(reflection_probe_set_enable_shadows, RID, bool) - BIND2(reflection_probe_set_cull_mask, RID, uint32_t) - BIND2(reflection_probe_set_resolution, RID, int) - BIND2(reflection_probe_set_lod_threshold, RID, float) + FUNCRIDSPLIT(reflection_probe) + + FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) + FUNC2(reflection_probe_set_intensity, RID, float) + FUNC2(reflection_probe_set_ambient_color, RID, const Color &) + FUNC2(reflection_probe_set_ambient_energy, RID, float) + FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode) + FUNC2(reflection_probe_set_max_distance, RID, float) + FUNC2(reflection_probe_set_extents, RID, const Vector3 &) + FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &) + FUNC2(reflection_probe_set_as_interior, RID, bool) + FUNC2(reflection_probe_set_enable_box_projection, RID, bool) + FUNC2(reflection_probe_set_enable_shadows, RID, bool) + FUNC2(reflection_probe_set_cull_mask, RID, uint32_t) + FUNC2(reflection_probe_set_resolution, RID, int) + FUNC2(reflection_probe_set_lod_threshold, RID, float) /* DECAL API */ - BIND0R(RID, decal_create) + FUNCRIDSPLIT(decal) - BIND2(decal_set_extents, RID, const Vector3 &) - BIND3(decal_set_texture, RID, DecalTexture, RID) - BIND2(decal_set_emission_energy, RID, float) - BIND2(decal_set_albedo_mix, RID, float) - BIND2(decal_set_modulate, RID, const Color &) - BIND2(decal_set_cull_mask, RID, uint32_t) - BIND4(decal_set_distance_fade, RID, bool, float, float) - BIND3(decal_set_fade, RID, float, float) - BIND2(decal_set_normal_fade, RID, float) + FUNC2(decal_set_extents, RID, const Vector3 &) + FUNC3(decal_set_texture, RID, DecalTexture, RID) + FUNC2(decal_set_emission_energy, RID, float) + FUNC2(decal_set_albedo_mix, RID, float) + FUNC2(decal_set_modulate, RID, const Color &) + FUNC2(decal_set_cull_mask, RID, uint32_t) + FUNC4(decal_set_distance_fade, RID, bool, float, float) + FUNC3(decal_set_fade, RID, float, float) + FUNC2(decal_set_normal_fade, RID, float) /* BAKED LIGHT API */ - BIND0R(RID, gi_probe_create) + FUNCRIDSPLIT(gi_probe) - BIND8(gi_probe_allocate, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) + FUNC8(gi_probe_allocate_data, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) - BIND1RC(AABB, gi_probe_get_bounds, RID) - BIND1RC(Vector3i, gi_probe_get_octree_size, RID) - BIND1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) - BIND1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) - BIND1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) - BIND1RC(Vector<int>, gi_probe_get_level_counts, RID) - BIND1RC(Transform, gi_probe_get_to_cell_xform, RID) + FUNC1RC(AABB, gi_probe_get_bounds, RID) + FUNC1RC(Vector3i, gi_probe_get_octree_size, RID) + FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) + FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) + FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) + FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID) + FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID) - BIND2(gi_probe_set_dynamic_range, RID, float) - BIND1RC(float, gi_probe_get_dynamic_range, RID) + FUNC2(gi_probe_set_dynamic_range, RID, float) + FUNC1RC(float, gi_probe_get_dynamic_range, RID) - BIND2(gi_probe_set_propagation, RID, float) - BIND1RC(float, gi_probe_get_propagation, RID) + FUNC2(gi_probe_set_propagation, RID, float) + FUNC1RC(float, gi_probe_get_propagation, RID) - BIND2(gi_probe_set_energy, RID, float) - BIND1RC(float, gi_probe_get_energy, RID) + FUNC2(gi_probe_set_energy, RID, float) + FUNC1RC(float, gi_probe_get_energy, RID) - BIND2(gi_probe_set_ao, RID, float) - BIND1RC(float, gi_probe_get_ao, RID) + FUNC2(gi_probe_set_ao, RID, float) + FUNC1RC(float, gi_probe_get_ao, RID) - BIND2(gi_probe_set_ao_size, RID, float) - BIND1RC(float, gi_probe_get_ao_size, RID) + FUNC2(gi_probe_set_ao_size, RID, float) + FUNC1RC(float, gi_probe_get_ao_size, RID) - BIND2(gi_probe_set_bias, RID, float) - BIND1RC(float, gi_probe_get_bias, RID) + FUNC2(gi_probe_set_bias, RID, float) + FUNC1RC(float, gi_probe_get_bias, RID) - BIND2(gi_probe_set_normal_bias, RID, float) - BIND1RC(float, gi_probe_get_normal_bias, RID) + FUNC2(gi_probe_set_normal_bias, RID, float) + FUNC1RC(float, gi_probe_get_normal_bias, RID) - BIND2(gi_probe_set_interior, RID, bool) - BIND1RC(bool, gi_probe_is_interior, RID) + FUNC2(gi_probe_set_interior, RID, bool) + FUNC1RC(bool, gi_probe_is_interior, RID) - BIND2(gi_probe_set_use_two_bounces, RID, bool) - BIND1RC(bool, gi_probe_is_using_two_bounces, RID) + FUNC2(gi_probe_set_use_two_bounces, RID, bool) + FUNC1RC(bool, gi_probe_is_using_two_bounces, RID) - BIND2(gi_probe_set_anisotropy_strength, RID, float) - BIND1RC(float, gi_probe_get_anisotropy_strength, RID) + FUNC2(gi_probe_set_anisotropy_strength, RID, float) + FUNC1RC(float, gi_probe_get_anisotropy_strength, RID) /* LIGHTMAP */ - BIND0R(RID, lightmap_create) + FUNCRIDSPLIT(lightmap) - BIND3(lightmap_set_textures, RID, RID, bool) - BIND2(lightmap_set_probe_bounds, RID, const AABB &) - BIND2(lightmap_set_probe_interior, RID, bool) - BIND5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) - BIND1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) - BIND1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) - BIND1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) - BIND1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) - BIND1(lightmap_set_probe_capture_update_speed, float) + FUNC3(lightmap_set_textures, RID, RID, bool) + FUNC2(lightmap_set_probe_bounds, RID, const AABB &) + FUNC2(lightmap_set_probe_interior, RID, bool) + FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) + FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) + FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) + FUNC1(lightmap_set_probe_capture_update_speed, float) /* PARTICLES */ - BIND0R(RID, particles_create) - - BIND2(particles_set_emitting, RID, bool) - BIND1R(bool, particles_get_emitting, RID) - BIND2(particles_set_amount, RID, int) - BIND2(particles_set_lifetime, RID, float) - BIND2(particles_set_one_shot, RID, bool) - BIND2(particles_set_pre_process_time, RID, float) - BIND2(particles_set_explosiveness_ratio, RID, float) - BIND2(particles_set_randomness_ratio, RID, float) - BIND2(particles_set_custom_aabb, RID, const AABB &) - BIND2(particles_set_speed_scale, RID, float) - BIND2(particles_set_use_local_coordinates, RID, bool) - BIND2(particles_set_process_material, RID, RID) - BIND2(particles_set_fixed_fps, RID, int) - BIND2(particles_set_fractional_delta, RID, bool) - BIND1R(bool, particles_is_inactive, RID) - BIND1(particles_request_process, RID) - BIND1(particles_restart, RID) - BIND6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) - BIND2(particles_set_subemitter, RID, RID) - BIND2(particles_set_collision_base_size, RID, float) - - BIND2(particles_set_draw_order, RID, RS::ParticlesDrawOrder) - - BIND2(particles_set_draw_passes, RID, int) - BIND3(particles_set_draw_pass_mesh, RID, int, RID) - - BIND1R(AABB, particles_get_current_aabb, RID) - BIND2(particles_set_emission_transform, RID, const Transform &) + FUNCRIDSPLIT(particles) + + FUNC2(particles_set_emitting, RID, bool) + FUNC1R(bool, particles_get_emitting, RID) + FUNC2(particles_set_amount, RID, int) + FUNC2(particles_set_lifetime, RID, float) + FUNC2(particles_set_one_shot, RID, bool) + FUNC2(particles_set_pre_process_time, RID, float) + FUNC2(particles_set_explosiveness_ratio, RID, float) + FUNC2(particles_set_randomness_ratio, RID, float) + FUNC2(particles_set_custom_aabb, RID, const AABB &) + FUNC2(particles_set_speed_scale, RID, float) + FUNC2(particles_set_use_local_coordinates, RID, bool) + FUNC2(particles_set_process_material, RID, RID) + FUNC2(particles_set_fixed_fps, RID, int) + FUNC2(particles_set_fractional_delta, RID, bool) + FUNC1R(bool, particles_is_inactive, RID) + FUNC1(particles_request_process, RID) + FUNC1(particles_restart, RID) + FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) + FUNC2(particles_set_subemitter, RID, RID) + FUNC2(particles_set_collision_base_size, RID, float) + + FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder) + + FUNC2(particles_set_draw_passes, RID, int) + FUNC3(particles_set_draw_pass_mesh, RID, int, RID) + + FUNC1R(AABB, particles_get_current_aabb, RID) + FUNC2(particles_set_emission_transform, RID, const Transform &) /* PARTICLES COLLISION */ - BIND0R(RID, particles_collision_create) - - BIND2(particles_collision_set_collision_type, RID, ParticlesCollisionType) - BIND2(particles_collision_set_cull_mask, RID, uint32_t) - BIND2(particles_collision_set_sphere_radius, RID, float) - BIND2(particles_collision_set_box_extents, RID, const Vector3 &) - BIND2(particles_collision_set_attractor_strength, RID, float) - BIND2(particles_collision_set_attractor_directionality, RID, float) - BIND2(particles_collision_set_attractor_attenuation, RID, float) - BIND2(particles_collision_set_field_texture, RID, RID) - BIND1(particles_collision_height_field_update, RID) - BIND2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution) - -#undef BINDBASE + FUNCRIDSPLIT(particles_collision) + + FUNC2(particles_collision_set_collision_type, RID, ParticlesCollisionType) + FUNC2(particles_collision_set_cull_mask, RID, uint32_t) + FUNC2(particles_collision_set_sphere_radius, RID, float) + FUNC2(particles_collision_set_box_extents, RID, const Vector3 &) + FUNC2(particles_collision_set_attractor_strength, RID, float) + FUNC2(particles_collision_set_attractor_directionality, RID, float) + FUNC2(particles_collision_set_attractor_attenuation, RID, float) + FUNC2(particles_collision_set_field_texture, RID, RID) + FUNC1(particles_collision_height_field_update, RID) + FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution) + +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::scene +#define ServerName RendererScene +#define server_name RSG::scene /* CAMERA API */ - BIND0R(RID, camera_create) - BIND4(camera_set_perspective, RID, float, float, float) - BIND4(camera_set_orthogonal, RID, float, float, float) - BIND5(camera_set_frustum, RID, float, Vector2, float, float) - BIND2(camera_set_transform, RID, const Transform &) - BIND2(camera_set_cull_mask, RID, uint32_t) - BIND2(camera_set_environment, RID, RID) - BIND2(camera_set_camera_effects, RID, RID) - BIND2(camera_set_use_vertical_aspect, RID, bool) - -#undef BINDBASE + FUNCRIDSPLIT(camera) + FUNC4(camera_set_perspective, RID, float, float, float) + FUNC4(camera_set_orthogonal, RID, float, float, float) + FUNC5(camera_set_frustum, RID, float, Vector2, float, float) + FUNC2(camera_set_transform, RID, const Transform &) + FUNC2(camera_set_cull_mask, RID, uint32_t) + FUNC2(camera_set_environment, RID, RID) + FUNC2(camera_set_camera_effects, RID, RID) + FUNC2(camera_set_use_vertical_aspect, RID, bool) + +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::viewport +#define ServerName RendererViewport +#define server_name RSG::viewport /* VIEWPORT TARGET API */ - BIND0R(RID, viewport_create) + FUNCRIDSPLIT(viewport) - BIND2(viewport_set_use_xr, RID, bool) - BIND3(viewport_set_size, RID, int, int) + FUNC2(viewport_set_use_xr, RID, bool) + FUNC3(viewport_set_size, RID, int, int) - BIND2(viewport_set_active, RID, bool) - BIND2(viewport_set_parent_viewport, RID, RID) + FUNC2(viewport_set_active, RID, bool) + FUNC2(viewport_set_parent_viewport, RID, RID) - BIND2(viewport_set_clear_mode, RID, ViewportClearMode) + FUNC2(viewport_set_clear_mode, RID, ViewportClearMode) - BIND3(viewport_attach_to_screen, RID, const Rect2 &, int) - BIND2(viewport_set_render_direct_to_screen, RID, bool) + FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int) + FUNC2(viewport_set_render_direct_to_screen, RID, bool) - BIND2(viewport_set_update_mode, RID, ViewportUpdateMode) - BIND2(viewport_set_vflip, RID, bool) + FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) - BIND1RC(RID, viewport_get_texture, RID) + FUNC1RC(RID, viewport_get_texture, RID) - BIND2(viewport_set_hide_scenario, RID, bool) - BIND2(viewport_set_hide_canvas, RID, bool) - BIND2(viewport_set_disable_environment, RID, bool) + FUNC2(viewport_set_hide_scenario, RID, bool) + FUNC2(viewport_set_hide_canvas, RID, bool) + FUNC2(viewport_set_disable_environment, RID, bool) - BIND2(viewport_attach_camera, RID, RID) - BIND2(viewport_set_scenario, RID, RID) - BIND2(viewport_attach_canvas, RID, RID) + FUNC2(viewport_attach_camera, RID, RID) + FUNC2(viewport_set_scenario, RID, RID) + FUNC2(viewport_attach_canvas, RID, RID) - BIND2(viewport_remove_canvas, RID, RID) - BIND3(viewport_set_canvas_transform, RID, RID, const Transform2D &) - BIND2(viewport_set_transparent_background, RID, bool) - BIND2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) - BIND2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) + FUNC2(viewport_remove_canvas, RID, RID) + FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &) + FUNC2(viewport_set_transparent_background, RID, bool) + FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) + FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) - BIND2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) - BIND2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat) + FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) + FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat) - BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &) - BIND4(viewport_set_canvas_stacking, RID, RID, int, int) - BIND3(viewport_set_shadow_atlas_size, RID, int, bool) - BIND3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) - BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) - BIND2(viewport_set_msaa, RID, ViewportMSAA) - BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) - BIND2(viewport_set_use_debanding, RID, bool) - BIND2(viewport_set_lod_threshold, RID, float) + FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &) + FUNC4(viewport_set_canvas_stacking, RID, RID, int, int) + FUNC3(viewport_set_shadow_atlas_size, RID, int, bool) + FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) + FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) + FUNC2(viewport_set_msaa, RID, ViewportMSAA) + FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) + FUNC2(viewport_set_use_debanding, RID, bool) + FUNC2(viewport_set_lod_threshold, RID, float) - BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo) - BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw) + FUNC2R(int, viewport_get_render_info, RID, ViewportRenderInfo) + FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw) - BIND2(viewport_set_measure_render_time, RID, bool) - BIND1RC(float, viewport_get_measured_render_time_cpu, RID) - BIND1RC(float, viewport_get_measured_render_time_gpu, RID) + FUNC2(viewport_set_measure_render_time, RID, bool) + FUNC1RC(float, viewport_get_measured_render_time_cpu, RID) + FUNC1RC(float, viewport_get_measured_render_time_gpu, RID) + + FUNC1(call_set_use_vsync, bool) /* ENVIRONMENT API */ -#undef BINDBASE +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::scene +#define ServerName RendererScene +#define server_name RSG::scene - BIND2(directional_shadow_atlas_set_size, int, bool) - BIND1(gi_probe_set_quality, GIProbeQuality) + FUNC2(directional_shadow_atlas_set_size, int, bool) + FUNC1(gi_probe_set_quality, GIProbeQuality) /* SKY API */ - BIND0R(RID, sky_create) - BIND2(sky_set_radiance_size, RID, int) - BIND2(sky_set_mode, RID, SkyMode) - BIND2(sky_set_material, RID, RID) - BIND4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) + FUNCRIDSPLIT(sky) + FUNC2(sky_set_radiance_size, RID, int) + FUNC2(sky_set_mode, RID, SkyMode) + FUNC2(sky_set_material, RID, RID) + FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) - BIND0R(RID, environment_create) + FUNCRIDSPLIT(environment) - BIND2(environment_set_background, RID, EnvironmentBG) - BIND2(environment_set_sky, RID, RID) - BIND2(environment_set_sky_custom_fov, RID, float) - BIND2(environment_set_sky_orientation, RID, const Basis &) - BIND2(environment_set_bg_color, RID, const Color &) - BIND2(environment_set_bg_energy, RID, float) - BIND2(environment_set_canvas_max_layer, RID, int) - BIND7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &) + FUNC2(environment_set_background, RID, EnvironmentBG) + FUNC2(environment_set_sky, RID, RID) + FUNC2(environment_set_sky_custom_fov, RID, float) + FUNC2(environment_set_sky_orientation, RID, const Basis &) + FUNC2(environment_set_bg_color, RID, const Color &) + FUNC2(environment_set_bg_energy, RID, float) + FUNC2(environment_set_canvas_max_layer, RID, int) + FUNC7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &) // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 - BIND2(environment_set_camera_feed_id, RID, int) + FUNC2(environment_set_camera_feed_id, RID, int) #endif - BIND6(environment_set_ssr, RID, bool, int, float, float, float) - BIND1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) + FUNC6(environment_set_ssr, RID, bool, int, float, float, float) + FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) - BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) - BIND6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float) + FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) + FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float) - BIND11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) - BIND1(environment_glow_set_use_bicubic_upscale, bool) - BIND1(environment_glow_set_use_high_quality, bool) + FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) + FUNC1(environment_glow_set_use_bicubic_upscale, bool) + FUNC1(environment_glow_set_use_high_quality, bool) - BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) + FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) - BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) - BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - BIND9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter) + FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) + FUNC10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float) - BIND2(environment_set_volumetric_fog_volume_size, int, int) - BIND1(environment_set_volumetric_fog_filter_active, bool) - BIND1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - BIND1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) + FUNC2(environment_set_volumetric_fog_volume_size, int, int) + FUNC1(environment_set_volumetric_fog_filter_active, bool) - BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) - BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) - BIND1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) - BIND1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight) + FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, float, bool, float, float, float) + FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) + FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) + FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight) - BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) - BIND3(screen_space_roughness_limiter_set_active, bool, float, float) - BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) - BIND2(sub_surface_scattering_set_scale, float, float) + FUNC3(screen_space_roughness_limiter_set_active, bool, float, float) + FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) + FUNC2(sub_surface_scattering_set_scale, float, float) /* CAMERA EFFECTS */ - BIND0R(RID, camera_effects_create) + FUNCRIDSPLIT(camera_effects) - BIND2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) - BIND1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) + FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) + FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) - BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) - BIND3(camera_effects_set_custom_exposure, RID, bool, float) + FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) + FUNC3(camera_effects_set_custom_exposure, RID, bool, float) - BIND1(shadows_quality_set, ShadowQuality); - BIND1(directional_shadow_quality_set, ShadowQuality); + FUNC1(shadows_quality_set, ShadowQuality); + FUNC1(directional_shadow_quality_set, ShadowQuality); /* SCENARIO API */ -#undef BINDBASE -#define BINDBASE RSG::scene +#undef server_name +#undef ServerName + +#define ServerName RendererScene +#define server_name RSG::scene - BIND0R(RID, scenario_create) + FUNCRIDSPLIT(scenario) - BIND2(scenario_set_debug, RID, ScenarioDebugMode) - BIND2(scenario_set_environment, RID, RID) - BIND2(scenario_set_camera_effects, RID, RID) - BIND2(scenario_set_fallback_environment, RID, RID) + FUNC2(scenario_set_debug, RID, ScenarioDebugMode) + FUNC2(scenario_set_environment, RID, RID) + FUNC2(scenario_set_camera_effects, RID, RID) + FUNC2(scenario_set_fallback_environment, RID, RID) /* INSTANCING API */ - BIND0R(RID, instance_create) + FUNCRIDSPLIT(instance) - BIND2(instance_set_base, RID, RID) - BIND2(instance_set_scenario, RID, RID) - BIND2(instance_set_layer_mask, RID, uint32_t) - BIND2(instance_set_transform, RID, const Transform &) - BIND2(instance_attach_object_instance_id, RID, ObjectID) - BIND3(instance_set_blend_shape_weight, RID, int, float) - BIND3(instance_set_surface_material, RID, int, RID) - BIND2(instance_set_visible, RID, bool) + FUNC2(instance_set_base, RID, RID) + FUNC2(instance_set_scenario, RID, RID) + FUNC2(instance_set_layer_mask, RID, uint32_t) + FUNC2(instance_set_transform, RID, const Transform &) + FUNC2(instance_attach_object_instance_id, RID, ObjectID) + FUNC3(instance_set_blend_shape_weight, RID, int, float) + FUNC3(instance_set_surface_material, RID, int, RID) + FUNC2(instance_set_visible, RID, bool) - BIND2(instance_set_custom_aabb, RID, AABB) + FUNC2(instance_set_custom_aabb, RID, AABB) - BIND2(instance_attach_skeleton, RID, RID) - BIND2(instance_set_exterior, RID, bool) + FUNC2(instance_attach_skeleton, RID, RID) + FUNC2(instance_set_exterior, RID, bool) - BIND2(instance_set_extra_visibility_margin, RID, real_t) + FUNC2(instance_set_extra_visibility_margin, RID, real_t) // don't use these in a game! - BIND2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) - BIND3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) - BIND2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) + FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) + FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) + FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) - BIND3(instance_geometry_set_flag, RID, InstanceFlags, bool) - BIND2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting) - BIND2(instance_geometry_set_material_override, RID, RID) + FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool) + FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting) + FUNC2(instance_geometry_set_material_override, RID, RID) - BIND5(instance_geometry_set_draw_range, RID, float, float, float, float) - BIND2(instance_geometry_set_as_instance_lod, RID, RID) - BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) - BIND2(instance_geometry_set_lod_bias, RID, float) + FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) + FUNC2(instance_geometry_set_as_instance_lod, RID, RID) + FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) + FUNC2(instance_geometry_set_lod_bias, RID, float) - BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) - BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) - BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) - BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) + FUNC2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) - BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) - BIND1(gi_set_use_half_resolution, bool) + FUNC1(gi_set_use_half_resolution, bool) -#undef BINDBASE +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::canvas +#define ServerName RendererCanvasCull +#define server_name RSG::canvas /* CANVAS (2D) */ - BIND0R(RID, canvas_create) - BIND3(canvas_set_item_mirroring, RID, RID, const Point2 &) - BIND2(canvas_set_modulate, RID, const Color &) - BIND3(canvas_set_parent, RID, RID, float) - BIND1(canvas_set_disable_scale, bool) - - BIND0R(RID, canvas_texture_create) - BIND3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID) - BIND3(canvas_texture_set_shading_parameters, RID, const Color &, float) - - BIND2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter) - BIND2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat) - - BIND0R(RID, canvas_item_create) - BIND2(canvas_item_set_parent, RID, RID) - - BIND2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter) - BIND2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat) - - BIND2(canvas_item_set_visible, RID, bool) - BIND2(canvas_item_set_light_mask, RID, int) - - BIND2(canvas_item_set_update_when_visible, RID, bool) - - BIND2(canvas_item_set_transform, RID, const Transform2D &) - BIND2(canvas_item_set_clip, RID, bool) - BIND2(canvas_item_set_distance_field_mode, RID, bool) - BIND3(canvas_item_set_custom_rect, RID, bool, const Rect2 &) - BIND2(canvas_item_set_modulate, RID, const Color &) - BIND2(canvas_item_set_self_modulate, RID, const Color &) - - BIND2(canvas_item_set_draw_behind_parent, RID, bool) - - BIND5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float) - BIND5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) - BIND4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) - BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &) - BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) - BIND6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) - BIND7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) - BIND10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &) - BIND6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float) - BIND5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID) - BIND9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int) - BIND5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID) - BIND3(canvas_item_add_multimesh, RID, RID, RID) - BIND3(canvas_item_add_particles, RID, RID, RID) - BIND2(canvas_item_add_set_transform, RID, const Transform2D &) - BIND2(canvas_item_add_clip_ignore, RID, bool) - BIND2(canvas_item_set_sort_children_by_y, RID, bool) - BIND2(canvas_item_set_z_index, RID, int) - BIND2(canvas_item_set_z_as_relative_to_parent, RID, bool) - BIND3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) - BIND2(canvas_item_attach_skeleton, RID, RID) - - BIND1(canvas_item_clear, RID) - BIND2(canvas_item_set_draw_index, RID, int) - - BIND2(canvas_item_set_material, RID, RID) - - BIND2(canvas_item_set_use_parent_material, RID, bool) - - BIND6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) - - BIND0R(RID, canvas_light_create) - - BIND2(canvas_light_set_mode, RID, CanvasLightMode) - - BIND2(canvas_light_attach_to_canvas, RID, RID) - BIND2(canvas_light_set_enabled, RID, bool) - BIND2(canvas_light_set_texture_scale, RID, float) - BIND2(canvas_light_set_transform, RID, const Transform2D &) - BIND2(canvas_light_set_texture, RID, RID) - BIND2(canvas_light_set_texture_offset, RID, const Vector2 &) - BIND2(canvas_light_set_color, RID, const Color &) - BIND2(canvas_light_set_height, RID, float) - BIND2(canvas_light_set_energy, RID, float) - BIND3(canvas_light_set_z_range, RID, int, int) - BIND3(canvas_light_set_layer_range, RID, int, int) - BIND2(canvas_light_set_item_cull_mask, RID, int) - BIND2(canvas_light_set_item_shadow_cull_mask, RID, int) - BIND2(canvas_light_set_directional_distance, RID, float) - - BIND2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) - - BIND2(canvas_light_set_shadow_enabled, RID, bool) - BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) - BIND2(canvas_light_set_shadow_color, RID, const Color &) - BIND2(canvas_light_set_shadow_smooth, RID, float) - - BIND0R(RID, canvas_light_occluder_create) - BIND2(canvas_light_occluder_attach_to_canvas, RID, RID) - BIND2(canvas_light_occluder_set_enabled, RID, bool) - BIND2(canvas_light_occluder_set_polygon, RID, RID) - BIND2(canvas_light_occluder_set_as_sdf_collision, RID, bool) - BIND2(canvas_light_occluder_set_transform, RID, const Transform2D &) - BIND2(canvas_light_occluder_set_light_mask, RID, int) - - BIND0R(RID, canvas_occluder_polygon_create) - BIND3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool) - - BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) - - BIND1(canvas_set_shadow_texture_size, int) + FUNCRIDSPLIT(canvas) + FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) + FUNC2(canvas_set_modulate, RID, const Color &) + FUNC3(canvas_set_parent, RID, RID, float) + FUNC1(canvas_set_disable_scale, bool) + + FUNCRIDSPLIT(canvas_texture) + FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID) + FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float) + + FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter) + FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat) + + FUNCRIDSPLIT(canvas_item) + FUNC2(canvas_item_set_parent, RID, RID) + + FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter) + FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat) + + FUNC2(canvas_item_set_visible, RID, bool) + FUNC2(canvas_item_set_light_mask, RID, int) + + FUNC2(canvas_item_set_update_when_visible, RID, bool) + + FUNC2(canvas_item_set_transform, RID, const Transform2D &) + FUNC2(canvas_item_set_clip, RID, bool) + FUNC2(canvas_item_set_distance_field_mode, RID, bool) + FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &) + FUNC2(canvas_item_set_modulate, RID, const Color &) + FUNC2(canvas_item_set_self_modulate, RID, const Color &) + + FUNC2(canvas_item_set_draw_behind_parent, RID, bool) + + FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float) + FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) + FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) + FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) + FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) + FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) + FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) + FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &) + FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float) + FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID) + FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int) + FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID) + FUNC3(canvas_item_add_multimesh, RID, RID, RID) + FUNC3(canvas_item_add_particles, RID, RID, RID) + FUNC2(canvas_item_add_set_transform, RID, const Transform2D &) + FUNC2(canvas_item_add_clip_ignore, RID, bool) + FUNC2(canvas_item_set_sort_children_by_y, RID, bool) + FUNC2(canvas_item_set_z_index, RID, int) + FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool) + FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) + FUNC2(canvas_item_attach_skeleton, RID, RID) + + FUNC1(canvas_item_clear, RID) + FUNC2(canvas_item_set_draw_index, RID, int) + + FUNC2(canvas_item_set_material, RID, RID) + + FUNC2(canvas_item_set_use_parent_material, RID, bool) + + FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) + + FUNCRIDSPLIT(canvas_light) + + FUNC2(canvas_light_set_mode, RID, CanvasLightMode) + + FUNC2(canvas_light_attach_to_canvas, RID, RID) + FUNC2(canvas_light_set_enabled, RID, bool) + FUNC2(canvas_light_set_texture_scale, RID, float) + FUNC2(canvas_light_set_transform, RID, const Transform2D &) + FUNC2(canvas_light_set_texture, RID, RID) + FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &) + FUNC2(canvas_light_set_color, RID, const Color &) + FUNC2(canvas_light_set_height, RID, float) + FUNC2(canvas_light_set_energy, RID, float) + FUNC3(canvas_light_set_z_range, RID, int, int) + FUNC3(canvas_light_set_layer_range, RID, int, int) + FUNC2(canvas_light_set_item_cull_mask, RID, int) + FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int) + FUNC2(canvas_light_set_directional_distance, RID, float) + + FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) + + FUNC2(canvas_light_set_shadow_enabled, RID, bool) + FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) + FUNC2(canvas_light_set_shadow_color, RID, const Color &) + FUNC2(canvas_light_set_shadow_smooth, RID, float) + + FUNCRIDSPLIT(canvas_light_occluder) + FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID) + FUNC2(canvas_light_occluder_set_enabled, RID, bool) + FUNC2(canvas_light_occluder_set_polygon, RID, RID) + FUNC2(canvas_light_occluder_set_as_sdf_collision, RID, bool) + FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &) + FUNC2(canvas_light_occluder_set_light_mask, RID, int) + + FUNCRIDSPLIT(canvas_occluder_polygon) + FUNC3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool) + + FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) + + FUNC1(canvas_set_shadow_texture_size, int) /* GLOBAL VARIABLES */ -#undef BINDBASE +#undef server_name +#undef ServerName //from now on, calls forwarded to this singleton -#define BINDBASE RSG::storage +#define ServerName RendererStorage +#define server_name RSG::storage - BIND3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) - BIND1(global_variable_remove, const StringName &) - BIND0RC(Vector<StringName>, global_variable_get_list) - BIND2(global_variable_set, const StringName &, const Variant &) - BIND2(global_variable_set_override, const StringName &, const Variant &) - BIND1RC(GlobalVariableType, global_variable_get_type, const StringName &) - BIND1RC(Variant, global_variable_get, const StringName &) + FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) + FUNC1(global_variable_remove, const StringName &) + FUNC0RC(Vector<StringName>, global_variable_get_list) + FUNC2(global_variable_set, const StringName &, const Variant &) + FUNC2(global_variable_set_override, const StringName &, const Variant &) + FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &) + FUNC1RC(Variant, global_variable_get, const StringName &) - BIND1(global_variables_load_settings, bool) - BIND0(global_variables_clear) + FUNC1(global_variables_load_settings, bool) + FUNC0(global_variables_clear) + +#undef server_name +#undef ServerName +#undef WRITE_ACTION +#undef SYNC_DEBUG /* BLACK BARS */ - virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom); - virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom); + virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) override; + virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) override; /* FREE */ - virtual void free(RID p_rid); ///< free RIDs associated with the visual server + virtual void free(RID p_rid) override { + if (Thread::get_caller_id() == server_thread) { + command_queue.flush_if_pending(); + _free(p_rid); + } else { + command_queue.push(this, &RenderingServerDefault::_free, p_rid); + } + } /* EVENT QUEUING */ - virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata); + virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) override; - virtual void draw(bool p_swap_buffers, double frame_step); - virtual void sync(); - virtual bool has_changed() const; - virtual void init(); - virtual void finish(); + virtual void draw(bool p_swap_buffers, double frame_step) override; + virtual void sync() override; + virtual bool has_changed() const override; + virtual void init() override; + virtual void finish() override; /* STATUS INFORMATION */ - virtual int get_render_info(RenderInfo p_info); - virtual String get_video_adapter_name() const; - virtual String get_video_adapter_vendor() const; + virtual int get_render_info(RenderInfo p_info) override; + virtual String get_video_adapter_name() const override; + virtual String get_video_adapter_vendor() const override; - virtual void set_frame_profiling_enabled(bool p_enable); - virtual Vector<FrameProfileArea> get_frame_profile(); - virtual uint64_t get_frame_profile_frame(); + virtual void set_frame_profiling_enabled(bool p_enable) override; + virtual Vector<FrameProfileArea> get_frame_profile() override; + virtual uint64_t get_frame_profile_frame() override; - virtual RID get_test_cube(); + virtual RID get_test_cube() override; /* TESTING */ - virtual float get_frame_setup_time_cpu() const; - - virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true); - virtual void set_default_clear_color(const Color &p_color); + virtual float get_frame_setup_time_cpu() const override; - virtual bool has_feature(Features p_feature) const; + virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override; + virtual void set_default_clear_color(const Color &p_color) override; - virtual bool has_os_feature(const String &p_feature) const; - virtual void set_debug_generate_wireframes(bool p_generate); + virtual bool has_feature(Features p_feature) const override; - virtual void call_set_use_vsync(bool p_enable); + virtual bool has_os_feature(const String &p_feature) const override; + virtual void set_debug_generate_wireframes(bool p_generate) override; - virtual bool is_low_end() const; + virtual bool is_low_end() const override; - virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir); + virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override; - virtual void set_print_gpu_profile(bool p_enable); + virtual void set_print_gpu_profile(bool p_enable) override; - RenderingServerDefault(); + RenderingServerDefault(bool p_create_thread = false); ~RenderingServerDefault(); - -#undef DISPLAY_CHANGED - -#undef BIND0R -#undef BIND1RC -#undef BIND2RC -#undef BIND3RC -#undef BIND4RC - -#undef BIND1 -#undef BIND2 -#undef BIND3 -#undef BIND4 -#undef BIND5 -#undef BIND6 -#undef BIND7 -#undef BIND8 -#undef BIND9 -#undef BIND10 }; #endif diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp deleted file mode 100644 index 9b8d35e5b3..0000000000 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************/ -/* rendering_server_wrap_mt.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 "rendering_server_wrap_mt.h" -#include "core/config/project_settings.h" -#include "core/os/os.h" -#include "servers/display_server.h" - -void RenderingServerWrapMT::thread_exit() { - exit = true; -} - -void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) { - if (!atomic_decrement(&draw_pending)) { - rendering_server->draw(p_swap_buffers, frame_step); - } -} - -void RenderingServerWrapMT::thread_flush() { - atomic_decrement(&draw_pending); -} - -void RenderingServerWrapMT::_thread_callback(void *_instance) { - RenderingServerWrapMT *vsmt = reinterpret_cast<RenderingServerWrapMT *>(_instance); - - vsmt->thread_loop(); -} - -void RenderingServerWrapMT::thread_loop() { - server_thread = Thread::get_caller_id(); - - DisplayServer::get_singleton()->make_rendering_thread(); - - rendering_server->init(); - - exit = false; - draw_thread_up = true; - while (!exit) { - // flush commands one by one, until exit is requested - command_queue.wait_and_flush_one(); - } - - command_queue.flush_all(); // flush all - - rendering_server->finish(); -} - -/* EVENT QUEUING */ - -void RenderingServerWrapMT::sync() { - if (create_thread) { - atomic_increment(&draw_pending); - command_queue.push_and_sync(this, &RenderingServerWrapMT::thread_flush); - } else { - command_queue.flush_all(); //flush all pending from other threads - } -} - -void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) { - if (create_thread) { - atomic_increment(&draw_pending); - command_queue.push(this, &RenderingServerWrapMT::thread_draw, p_swap_buffers, frame_step); - } else { - rendering_server->draw(p_swap_buffers, frame_step); - } -} - -void RenderingServerWrapMT::init() { - if (create_thread) { - print_verbose("RenderingServerWrapMT: Creating render thread"); - DisplayServer::get_singleton()->release_rendering_thread(); - if (create_thread) { - thread.start(_thread_callback, this); - print_verbose("RenderingServerWrapMT: Starting render thread"); - } - while (!draw_thread_up) { - OS::get_singleton()->delay_usec(1000); - } - print_verbose("RenderingServerWrapMT: Finished render thread"); - } else { - rendering_server->init(); - } -} - -void RenderingServerWrapMT::finish() { - sky_free_cached_ids(); - shader_free_cached_ids(); - material_free_cached_ids(); - mesh_free_cached_ids(); - multimesh_free_cached_ids(); - immediate_free_cached_ids(); - skeleton_free_cached_ids(); - directional_light_free_cached_ids(); - omni_light_free_cached_ids(); - spot_light_free_cached_ids(); - reflection_probe_free_cached_ids(); - gi_probe_free_cached_ids(); - lightmap_free_cached_ids(); - particles_free_cached_ids(); - particles_collision_free_cached_ids(); - camera_free_cached_ids(); - viewport_free_cached_ids(); - environment_free_cached_ids(); - camera_effects_free_cached_ids(); - scenario_free_cached_ids(); - instance_free_cached_ids(); - canvas_free_cached_ids(); - canvas_item_free_cached_ids(); - canvas_light_occluder_free_cached_ids(); - canvas_occluder_polygon_free_cached_ids(); - - if (create_thread) { - command_queue.push(this, &RenderingServerWrapMT::thread_exit); - thread.wait_to_finish(); - } else { - rendering_server->finish(); - } -} - -void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { - singleton_mt->call_set_use_vsync(p_enable); -} - -RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr; - -RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) : - command_queue(p_create_thread) { - singleton_mt = this; - DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly - - rendering_server = p_contained; - create_thread = p_create_thread; - draw_pending = 0; - draw_thread_up = false; - pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); - - if (!p_create_thread) { - server_thread = Thread::get_caller_id(); - } else { - server_thread = 0; - } -} - -RenderingServerWrapMT::~RenderingServerWrapMT() { - memdelete(rendering_server); - //finish(); -} diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h deleted file mode 100644 index f8e73654a0..0000000000 --- a/servers/rendering/rendering_server_wrap_mt.h +++ /dev/null @@ -1,810 +0,0 @@ -/*************************************************************************/ -/* rendering_server_wrap_mt.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 RENDERING_SERVER_WRAP_MT_H -#define RENDERING_SERVER_WRAP_MT_H - -#include "core/os/thread.h" -#include "core/templates/command_queue_mt.h" -#include "servers/rendering_server.h" - -class RenderingServerWrapMT : public RenderingServer { - // the real visual server - mutable RenderingServer *rendering_server; - - mutable CommandQueueMT command_queue; - - static void _thread_callback(void *_instance); - void thread_loop(); - - Thread::ID server_thread; - volatile bool exit; - Thread thread; - volatile bool draw_thread_up; - bool create_thread; - - uint64_t draw_pending; - void thread_draw(bool p_swap_buffers, double frame_step); - void thread_flush(); - - void thread_exit(); - - Mutex alloc_mutex; - - int pool_max_size; - - //#define DEBUG_SYNC - - static RenderingServerWrapMT *singleton_mt; - -#ifdef DEBUG_SYNC -#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); -#else -#define SYNC_DEBUG -#endif - -public: -#define ServerName RenderingServer -#define ServerNameWrapMT RenderingServerWrapMT -#define server_name rendering_server -#include "servers/server_wrap_mt_common.h" - - //these go pass-through, as they can be called from any thread - virtual RID texture_2d_create(const Ref<Image> &p_image) { return rendering_server->texture_2d_create(p_image); } - virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) { return rendering_server->texture_2d_layered_create(p_layers, p_layered_type); } - virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { return rendering_server->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); } - virtual RID texture_proxy_create(RID p_base) { return rendering_server->texture_proxy_create(p_base); } - - //goes pass-through - virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) { rendering_server->texture_2d_update_immediate(p_texture, p_image, p_layer); } - //these go through command queue if they are in another thread - FUNC3(texture_2d_update, RID, const Ref<Image> &, int) - FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &) - FUNC2(texture_proxy_update, RID, RID) - - //these also go pass-through - virtual RID texture_2d_placeholder_create() { return rendering_server->texture_2d_placeholder_create(); } - virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_type) { return rendering_server->texture_2d_layered_placeholder_create(p_type); } - virtual RID texture_3d_placeholder_create() { return rendering_server->texture_3d_placeholder_create(); } - - FUNC1RC(Ref<Image>, texture_2d_get, RID) - FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int) - FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID) - - FUNC2(texture_replace, RID, RID) - - FUNC3(texture_set_size_override, RID, int, int) -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - FUNC2(texture_bind, RID, uint32_t) -#endif - - FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *) - FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *) - FUNC3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *) - - FUNC2(texture_set_path, RID, const String &) - FUNC1RC(String, texture_get_path, RID) - FUNC1S(texture_debug_usage, List<TextureInfo> *) - - FUNC2(texture_set_force_redraw_if_visible, RID, bool) - - /* SHADER API */ - - FUNCRID(shader) - - FUNC2(shader_set_code, RID, const String &) - FUNC1RC(String, shader_get_code, RID) - - FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *) - - FUNC3(shader_set_default_texture_param, RID, const StringName &, RID) - FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &) - FUNC2RC(Variant, shader_get_param_default, RID, const StringName &) - - FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID) - - /* COMMON MATERIAL API */ - - FUNCRID(material) - - FUNC2(material_set_shader, RID, RID) - - FUNC3(material_set_param, RID, const StringName &, const Variant &) - FUNC2RC(Variant, material_get_param, RID, const StringName &) - - FUNC2(material_set_render_priority, RID, int) - FUNC2(material_set_next_pass, RID, RID) - - /* MESH API */ - - virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) { - return rendering_server->mesh_create_from_surfaces(p_surfaces, p_blend_shape_count); - } - - FUNC2(mesh_set_blend_shape_count, RID, int) - - FUNCRID(mesh) - - FUNC2(mesh_add_surface, RID, const SurfaceData &) - - FUNC1RC(int, mesh_get_blend_shape_count, RID) - - FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode) - FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID) - - FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &) - - FUNC3(mesh_surface_set_material, RID, int, RID) - FUNC2RC(RID, mesh_surface_get_material, RID, int) - - FUNC2RC(SurfaceData, mesh_get_surface, RID, int) - - FUNC1RC(int, mesh_get_surface_count, RID) - - FUNC2(mesh_set_custom_aabb, RID, const AABB &) - FUNC1RC(AABB, mesh_get_custom_aabb, RID) - - FUNC2(mesh_set_shadow_mesh, RID, RID) - FUNC1(mesh_clear, RID) - - /* MULTIMESH API */ - - FUNCRID(multimesh) - - FUNC5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool) - FUNC1RC(int, multimesh_get_instance_count, RID) - - FUNC2(multimesh_set_mesh, RID, RID) - FUNC3(multimesh_instance_set_transform, RID, int, const Transform &) - FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &) - FUNC3(multimesh_instance_set_color, RID, int, const Color &) - FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &) - - FUNC1RC(RID, multimesh_get_mesh, RID) - FUNC1RC(AABB, multimesh_get_aabb, RID) - - FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) - FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) - FUNC2RC(Color, multimesh_instance_get_color, RID, int) - FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int) - - FUNC2(multimesh_set_buffer, RID, const Vector<float> &) - FUNC1RC(Vector<float>, multimesh_get_buffer, RID) - - FUNC2(multimesh_set_visible_instances, RID, int) - FUNC1RC(int, multimesh_get_visible_instances, RID) - - /* IMMEDIATE API */ - - FUNCRID(immediate) - FUNC3(immediate_begin, RID, PrimitiveType, RID) - FUNC2(immediate_vertex, RID, const Vector3 &) - FUNC2(immediate_normal, RID, const Vector3 &) - FUNC2(immediate_tangent, RID, const Plane &) - FUNC2(immediate_color, RID, const Color &) - FUNC2(immediate_uv, RID, const Vector2 &) - FUNC2(immediate_uv2, RID, const Vector2 &) - FUNC1(immediate_end, RID) - FUNC1(immediate_clear, RID) - FUNC2(immediate_set_material, RID, RID) - FUNC1RC(RID, immediate_get_material, RID) - - /* SKELETON API */ - - FUNCRID(skeleton) - FUNC3(skeleton_allocate, RID, int, bool) - FUNC1RC(int, skeleton_get_bone_count, RID) - FUNC3(skeleton_bone_set_transform, RID, int, const Transform &) - FUNC2RC(Transform, skeleton_bone_get_transform, RID, int) - FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &) - FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int) - FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &) - - /* Light API */ - - FUNCRID(directional_light) - FUNCRID(omni_light) - FUNCRID(spot_light) - - FUNC2(light_set_color, RID, const Color &) - FUNC3(light_set_param, RID, LightParam, float) - FUNC2(light_set_shadow, RID, bool) - FUNC2(light_set_shadow_color, RID, const Color &) - FUNC2(light_set_projector, RID, RID) - FUNC2(light_set_negative, RID, bool) - FUNC2(light_set_cull_mask, RID, uint32_t) - FUNC2(light_set_reverse_cull_face_mode, RID, bool) - FUNC2(light_set_bake_mode, RID, LightBakeMode) - FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t) - - FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode) - - FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) - FUNC2(light_directional_set_blend_splits, RID, bool) - FUNC2(light_directional_set_sky_only, RID, bool) - FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) - - /* PROBE API */ - - FUNCRID(reflection_probe) - - FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode) - FUNC2(reflection_probe_set_intensity, RID, float) - FUNC2(reflection_probe_set_ambient_color, RID, const Color &) - FUNC2(reflection_probe_set_ambient_energy, RID, float) - FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode) - FUNC2(reflection_probe_set_max_distance, RID, float) - FUNC2(reflection_probe_set_extents, RID, const Vector3 &) - FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &) - FUNC2(reflection_probe_set_as_interior, RID, bool) - FUNC2(reflection_probe_set_enable_box_projection, RID, bool) - FUNC2(reflection_probe_set_enable_shadows, RID, bool) - FUNC2(reflection_probe_set_cull_mask, RID, uint32_t) - FUNC2(reflection_probe_set_resolution, RID, int) - FUNC2(reflection_probe_set_lod_threshold, RID, float) - - /* DECAL API */ - - FUNCRID(decal) - - FUNC2(decal_set_extents, RID, const Vector3 &) - FUNC3(decal_set_texture, RID, DecalTexture, RID) - FUNC2(decal_set_emission_energy, RID, float) - FUNC2(decal_set_albedo_mix, RID, float) - FUNC2(decal_set_modulate, RID, const Color &) - FUNC2(decal_set_cull_mask, RID, uint32_t) - FUNC4(decal_set_distance_fade, RID, bool, float, float) - FUNC3(decal_set_fade, RID, float, float) - FUNC2(decal_set_normal_fade, RID, float) - - /* BAKED LIGHT API */ - - FUNCRID(gi_probe) - - FUNC8(gi_probe_allocate, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &) - - FUNC1RC(AABB, gi_probe_get_bounds, RID) - FUNC1RC(Vector3i, gi_probe_get_octree_size, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID) - FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID) - FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID) - FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID) - - FUNC2(gi_probe_set_dynamic_range, RID, float) - FUNC1RC(float, gi_probe_get_dynamic_range, RID) - - FUNC2(gi_probe_set_propagation, RID, float) - FUNC1RC(float, gi_probe_get_propagation, RID) - - FUNC2(gi_probe_set_energy, RID, float) - FUNC1RC(float, gi_probe_get_energy, RID) - - FUNC2(gi_probe_set_ao, RID, float) - FUNC1RC(float, gi_probe_get_ao, RID) - - FUNC2(gi_probe_set_ao_size, RID, float) - FUNC1RC(float, gi_probe_get_ao_size, RID) - - FUNC2(gi_probe_set_bias, RID, float) - FUNC1RC(float, gi_probe_get_bias, RID) - - FUNC2(gi_probe_set_normal_bias, RID, float) - FUNC1RC(float, gi_probe_get_normal_bias, RID) - - FUNC2(gi_probe_set_interior, RID, bool) - FUNC1RC(bool, gi_probe_is_interior, RID) - - FUNC2(gi_probe_set_use_two_bounces, RID, bool) - FUNC1RC(bool, gi_probe_is_using_two_bounces, RID) - - FUNC2(gi_probe_set_anisotropy_strength, RID, float) - FUNC1RC(float, gi_probe_get_anisotropy_strength, RID) - - FUNC1(gi_probe_set_quality, GIProbeQuality) - - /* LIGHTMAP CAPTURE */ - - FUNCRID(lightmap) - FUNC3(lightmap_set_textures, RID, RID, bool) - FUNC2(lightmap_set_probe_bounds, RID, const AABB &) - FUNC2(lightmap_set_probe_interior, RID, bool) - FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) - FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) - FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) - FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) - FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) - - FUNC1(lightmap_set_probe_capture_update_speed, float) - - /* PARTICLES */ - - FUNCRID(particles) - - FUNC2(particles_set_emitting, RID, bool) - FUNC1R(bool, particles_get_emitting, RID) - FUNC2(particles_set_amount, RID, int) - FUNC2(particles_set_lifetime, RID, float) - FUNC2(particles_set_one_shot, RID, bool) - FUNC2(particles_set_pre_process_time, RID, float) - FUNC2(particles_set_explosiveness_ratio, RID, float) - FUNC2(particles_set_randomness_ratio, RID, float) - FUNC2(particles_set_custom_aabb, RID, const AABB &) - FUNC2(particles_set_speed_scale, RID, float) - FUNC2(particles_set_use_local_coordinates, RID, bool) - FUNC2(particles_set_process_material, RID, RID) - FUNC2(particles_set_fixed_fps, RID, int) - FUNC2(particles_set_fractional_delta, RID, bool) - FUNC2(particles_set_collision_base_size, RID, float) - - FUNC1R(bool, particles_is_inactive, RID) - FUNC1(particles_request_process, RID) - FUNC1(particles_restart, RID) - - FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t) - - FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder) - - FUNC2(particles_set_draw_passes, RID, int) - FUNC3(particles_set_draw_pass_mesh, RID, int, RID) - FUNC2(particles_set_emission_transform, RID, const Transform &) - FUNC2(particles_set_subemitter, RID, RID) - - FUNC1R(AABB, particles_get_current_aabb, RID) - - /* PARTICLES COLLISION */ - - FUNCRID(particles_collision) - - FUNC2(particles_collision_set_collision_type, RID, ParticlesCollisionType) - FUNC2(particles_collision_set_cull_mask, RID, uint32_t) - FUNC2(particles_collision_set_sphere_radius, RID, float) - FUNC2(particles_collision_set_box_extents, RID, const Vector3 &) - FUNC2(particles_collision_set_attractor_strength, RID, float) - FUNC2(particles_collision_set_attractor_directionality, RID, float) - FUNC2(particles_collision_set_attractor_attenuation, RID, float) - FUNC2(particles_collision_set_field_texture, RID, RID) - FUNC1(particles_collision_height_field_update, RID) - FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution) - - /* CAMERA API */ - - FUNCRID(camera) - FUNC4(camera_set_perspective, RID, float, float, float) - FUNC4(camera_set_orthogonal, RID, float, float, float) - FUNC5(camera_set_frustum, RID, float, Vector2, float, float) - FUNC2(camera_set_transform, RID, const Transform &) - FUNC2(camera_set_cull_mask, RID, uint32_t) - FUNC2(camera_set_environment, RID, RID) - FUNC2(camera_set_camera_effects, RID, RID) - FUNC2(camera_set_use_vertical_aspect, RID, bool) - - /* VIEWPORT TARGET API */ - - FUNCRID(viewport) - - FUNC2(viewport_set_use_xr, RID, bool) - - FUNC3(viewport_set_size, RID, int, int) - - FUNC2(viewport_set_active, RID, bool) - FUNC2(viewport_set_parent_viewport, RID, RID) - - FUNC2(viewport_set_clear_mode, RID, ViewportClearMode) - - FUNC3(viewport_attach_to_screen, RID, const Rect2 &, DisplayServer::WindowID) - FUNC2(viewport_set_render_direct_to_screen, RID, bool) - - FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) - - FUNC1RC(RID, viewport_get_texture, RID) - - FUNC2(viewport_set_hide_scenario, RID, bool) - FUNC2(viewport_set_hide_canvas, RID, bool) - FUNC2(viewport_set_disable_environment, RID, bool) - - FUNC2(viewport_attach_camera, RID, RID) - FUNC2(viewport_set_scenario, RID, RID) - FUNC2(viewport_attach_canvas, RID, RID) - - FUNC2(viewport_remove_canvas, RID, RID) - FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &) - FUNC2(viewport_set_transparent_background, RID, bool) - FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool) - FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool) - - FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter) - FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat) - - FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &) - FUNC4(viewport_set_canvas_stacking, RID, RID, int, int) - FUNC3(viewport_set_shadow_atlas_size, RID, int, bool) - FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) - - FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) - FUNC2(viewport_set_msaa, RID, ViewportMSAA) - FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) - FUNC2(viewport_set_use_debanding, RID, bool) - - FUNC2(viewport_set_lod_threshold, RID, float) - - //this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport - virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) { - return rendering_server->viewport_get_render_info(p_viewport, p_info); - } - - FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw) - - FUNC2(viewport_set_measure_render_time, RID, bool) - virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const { - return rendering_server->viewport_get_measured_render_time_cpu(p_viewport); - } - virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const { - return rendering_server->viewport_get_measured_render_time_gpu(p_viewport); - } - - FUNC2(directional_shadow_atlas_set_size, int, bool) - - /* SKY API */ - - FUNCRID(sky) - FUNC2(sky_set_radiance_size, RID, int) - FUNC2(sky_set_mode, RID, SkyMode) - FUNC2(sky_set_material, RID, RID) - FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) - - /* ENVIRONMENT API */ - - FUNCRID(environment) - - FUNC2(environment_set_background, RID, EnvironmentBG) - FUNC2(environment_set_sky, RID, RID) - FUNC2(environment_set_sky_custom_fov, RID, float) - FUNC2(environment_set_sky_orientation, RID, const Basis &) - FUNC2(environment_set_bg_color, RID, const Color &) - FUNC2(environment_set_bg_energy, RID, float) - FUNC2(environment_set_canvas_max_layer, RID, int) - FUNC7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &) - -// FIXME: Disabled during Vulkan refactoring, should be ported. -#if 0 - FUNC2(environment_set_camera_feed_id, RID, int) -#endif - FUNC6(environment_set_ssr, RID, bool, int, float, float, float) - FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality) - - FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) - - FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float) - - FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float) - FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount) - FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge) - FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight) - - FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float) - FUNC1(environment_glow_set_use_bicubic_upscale, bool) - FUNC1(environment_glow_set_use_high_quality, bool) - - FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float) - - FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) - - FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - - FUNC9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter) - - FUNC2(environment_set_volumetric_fog_volume_size, int, int) - FUNC1(environment_set_volumetric_fog_filter_active, bool) - FUNC1(environment_set_volumetric_fog_directional_shadow_shrink_size, int) - FUNC1(environment_set_volumetric_fog_positional_shadow_shrink_size, int) - - FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) - - FUNC3(screen_space_roughness_limiter_set_active, bool, float, float) - FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) - FUNC2(sub_surface_scattering_set_scale, float, float) - - FUNCRID(camera_effects) - - FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool) - FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape) - - FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) - FUNC3(camera_effects_set_custom_exposure, RID, bool, float) - - FUNC1(shadows_quality_set, ShadowQuality); - FUNC1(directional_shadow_quality_set, ShadowQuality); - - FUNCRID(scenario) - - FUNC2(scenario_set_debug, RID, ScenarioDebugMode) - FUNC2(scenario_set_environment, RID, RID) - FUNC2(scenario_set_camera_effects, RID, RID) - FUNC2(scenario_set_fallback_environment, RID, RID) - - /* INSTANCING API */ - FUNCRID(instance) - - FUNC2(instance_set_base, RID, RID) - FUNC2(instance_set_scenario, RID, RID) - FUNC2(instance_set_layer_mask, RID, uint32_t) - FUNC2(instance_set_transform, RID, const Transform &) - FUNC2(instance_attach_object_instance_id, RID, ObjectID) - FUNC3(instance_set_blend_shape_weight, RID, int, float) - FUNC3(instance_set_surface_material, RID, int, RID) - FUNC2(instance_set_visible, RID, bool) - - FUNC2(instance_set_custom_aabb, RID, AABB) - - FUNC2(instance_attach_skeleton, RID, RID) - FUNC2(instance_set_exterior, RID, bool) - - FUNC2(instance_set_extra_visibility_margin, RID, real_t) - - // don't use these in a game! - FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) - FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) - FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) - - FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool) - FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting) - FUNC2(instance_geometry_set_material_override, RID, RID) - - FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) - FUNC2(instance_geometry_set_as_instance_lod, RID, RID) - FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) - FUNC2(instance_geometry_set_lod_bias, RID, float) - - FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) - FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) - FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) - FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) - - /* BAKE */ - - FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) - - /* CANVAS (2D) */ - - FUNCRID(canvas) - FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &) - FUNC2(canvas_set_modulate, RID, const Color &) - FUNC3(canvas_set_parent, RID, RID, float) - FUNC1(canvas_set_disable_scale, bool) - - FUNCRID(canvas_texture) - FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID) - FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float) - - FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter) - FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat) - - FUNCRID(canvas_item) - FUNC2(canvas_item_set_parent, RID, RID) - - FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter) - FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat) - - FUNC2(canvas_item_set_visible, RID, bool) - FUNC2(canvas_item_set_light_mask, RID, int) - - FUNC2(canvas_item_set_update_when_visible, RID, bool) - - FUNC2(canvas_item_set_transform, RID, const Transform2D &) - FUNC2(canvas_item_set_clip, RID, bool) - FUNC2(canvas_item_set_distance_field_mode, RID, bool) - FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &) - FUNC2(canvas_item_set_modulate, RID, const Color &) - FUNC2(canvas_item_set_self_modulate, RID, const Color &) - - FUNC2(canvas_item_set_draw_behind_parent, RID, bool) - - FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float) - FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) - FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float) - FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) - FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) - FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool) - FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool) - FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &) - FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float) - FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID) - FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int) - FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID) - FUNC3(canvas_item_add_multimesh, RID, RID, RID) - FUNC3(canvas_item_add_particles, RID, RID, RID) - FUNC2(canvas_item_add_set_transform, RID, const Transform2D &) - FUNC2(canvas_item_add_clip_ignore, RID, bool) - FUNC2(canvas_item_set_sort_children_by_y, RID, bool) - FUNC2(canvas_item_set_z_index, RID, int) - FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool) - FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) - FUNC2(canvas_item_attach_skeleton, RID, RID) - - FUNC1(canvas_item_clear, RID) - FUNC2(canvas_item_set_draw_index, RID, int) - - FUNC2(canvas_item_set_material, RID, RID) - - FUNC2(canvas_item_set_use_parent_material, RID, bool) - - FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool) - - FUNC0R(RID, canvas_light_create) - - FUNC2(canvas_light_set_mode, RID, CanvasLightMode) - - FUNC2(canvas_light_attach_to_canvas, RID, RID) - FUNC2(canvas_light_set_enabled, RID, bool) - FUNC2(canvas_light_set_texture_scale, RID, float) - FUNC2(canvas_light_set_transform, RID, const Transform2D &) - FUNC2(canvas_light_set_texture, RID, RID) - FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &) - FUNC2(canvas_light_set_color, RID, const Color &) - FUNC2(canvas_light_set_height, RID, float) - FUNC2(canvas_light_set_energy, RID, float) - FUNC3(canvas_light_set_z_range, RID, int, int) - FUNC3(canvas_light_set_layer_range, RID, int, int) - FUNC2(canvas_light_set_item_cull_mask, RID, int) - FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int) - FUNC2(canvas_light_set_directional_distance, RID, float) - - FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode) - - FUNC2(canvas_light_set_shadow_enabled, RID, bool) - FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter) - FUNC2(canvas_light_set_shadow_color, RID, const Color &) - FUNC2(canvas_light_set_shadow_smooth, RID, float) - - FUNCRID(canvas_light_occluder) - FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID) - FUNC2(canvas_light_occluder_set_enabled, RID, bool) - FUNC2(canvas_light_occluder_set_polygon, RID, RID) - FUNC2(canvas_light_occluder_set_as_sdf_collision, RID, bool) - FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &) - FUNC2(canvas_light_occluder_set_light_mask, RID, int) - - FUNCRID(canvas_occluder_polygon) - FUNC3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool) - - FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) - - FUNC1(canvas_set_shadow_texture_size, int) - - /* GLOBAL VARIABLES */ - - FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) - FUNC1(global_variable_remove, const StringName &) - FUNC0RC(Vector<StringName>, global_variable_get_list) - FUNC2(global_variable_set, const StringName &, const Variant &) - FUNC2(global_variable_set_override, const StringName &, const Variant &) - FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &) - FUNC1RC(Variant, global_variable_get, const StringName &) - FUNC1(global_variables_load_settings, bool) - FUNC0(global_variables_clear) - - /* BLACK BARS */ - - FUNC4(black_bars_set_margins, int, int, int, int) - FUNC4(black_bars_set_images, RID, RID, RID, RID) - - /* FREE */ - - FUNC1(free, RID) - - /* EVENT QUEUING */ - - FUNC3(request_frame_drawn_callback, Object *, const StringName &, const Variant &) - - virtual void init(); - virtual void finish(); - virtual void draw(bool p_swap_buffers, double frame_step); - virtual void sync(); - FUNC0RC(bool, has_changed) - - /* RENDER INFO */ - - //this passes directly to avoid stalling - virtual int get_render_info(RenderInfo p_info) { - return rendering_server->get_render_info(p_info); - } - - virtual String get_video_adapter_name() const { - return rendering_server->get_video_adapter_name(); - } - - virtual String get_video_adapter_vendor() const { - return rendering_server->get_video_adapter_vendor(); - } - - FUNC1(gi_set_use_half_resolution, bool) - - FUNC4(set_boot_image, const Ref<Image> &, const Color &, bool, bool) - FUNC1(set_default_clear_color, const Color &) - - FUNC0R(RID, get_test_cube) - - FUNC1(set_debug_generate_wireframes, bool) - - virtual bool has_feature(Features p_feature) const { - return rendering_server->has_feature(p_feature); - } - virtual bool has_os_feature(const String &p_feature) const { - return rendering_server->has_os_feature(p_feature); - } - - FUNC1(call_set_use_vsync, bool) - - static void set_use_vsync_callback(bool p_enable); - - virtual bool is_low_end() const { - return rendering_server->is_low_end(); - } - - virtual uint64_t get_frame_profile_frame() { - return rendering_server->get_frame_profile_frame(); - } - - virtual void set_frame_profiling_enabled(bool p_enabled) { - rendering_server->set_frame_profiling_enabled(p_enabled); - } - - virtual Vector<FrameProfileArea> get_frame_profile() { - return rendering_server->get_frame_profile(); - } - - virtual float get_frame_setup_time_cpu() const { - return rendering_server->get_frame_setup_time_cpu(); - } - - virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { - rendering_server->sdfgi_set_debug_probe_select(p_position, p_dir); - } - - virtual void set_print_gpu_profile(bool p_enable) { - rendering_server->set_print_gpu_profile(p_enable); - } - - RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread); - ~RenderingServerWrapMT(); - -#undef ServerName -#undef ServerNameWrapMT -#undef server_name -}; - -#ifdef DEBUG_SYNC -#undef DEBUG_SYNC -#endif -#undef SYNC_DEBUG - -#endif diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index e6415c0258..e52d97e4d9 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -3102,6 +3102,72 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const { return false; } +bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) { + if (current_function == String("light")) { + *r_message = RTR("Varying may not be assigned in the 'light' function."); + return false; + } + switch (p_varying.stage) { + case ShaderNode::Varying::STAGE_UNKNOWN: // first assign + if (current_function == String("vertex")) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX; + } else if (current_function == String("fragment")) { + p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT; + } + break; + case ShaderNode::Varying::STAGE_VERTEX: + if (current_function == String("fragment")) { + *r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'."); + return false; + } + break; + case ShaderNode::Varying::STAGE_FRAGMENT: + if (current_function == String("vertex")) { + *r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'."); + return false; + } + break; + default: + break; + } + return true; +} + +bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, String *r_message) { + switch (p_varying.stage) { + case ShaderNode::Varying::STAGE_UNKNOWN: + *r_message = RTR("Varying must be assigned before using!"); + return false; + case ShaderNode::Varying::STAGE_VERTEX: + if (current_function == String("fragment")) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT; + } else if (current_function == String("light")) { + p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT; + } + break; + case ShaderNode::Varying::STAGE_FRAGMENT: + if (current_function == String("light")) { + p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT; + } + break; + case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT: + if (current_function == String("light")) { + *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); + return false; + } + break; + case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT: + if (current_function == String("fragment")) { + *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); + return false; + } + break; + default: + break; + } + return true; +} + bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) { if (p_node->type == Node::TYPE_OPERATOR) { OperatorNode *op = static_cast<OperatorNode *>(p_node); @@ -3142,13 +3208,6 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi return false; } - if (shader->varyings.has(var->name) && current_function != String("vertex")) { - if (r_message) { - *r_message = RTR("Varyings can only be assigned in vertex function."); - } - return false; - } - if (shader->constants.has(var->name) || var->is_const) { if (r_message) { *r_message = RTR("Constants cannot be modified."); @@ -3169,13 +3228,6 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi return false; } - if (shader->varyings.has(arr->name) && current_function != String("vertex")) { - if (r_message) { - *r_message = RTR("Varyings can only be assigned in vertex function."); - } - return false; - } - return true; } @@ -3761,6 +3813,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Unknown identifier in expression: " + String(identifier)); return nullptr; } + if (ident_type == IDENTIFIER_VARYING) { + TkPos prev_pos = _get_tkpos(); + Token next_token = _get_token(); + _set_tkpos(prev_pos); + String error; + if (next_token.type == TK_OP_ASSIGN) { + if (!_validate_varying_assign(shader->varyings[identifier], &error)) { + _set_error(error); + return nullptr; + } + } else { + if (!_validate_varying_using(shader->varyings[identifier], &error)) { + _set_error(error); + return nullptr; + } + } + } last_const = is_const; if (ident_type == IDENTIFIER_FUNCTION) { @@ -3786,10 +3855,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Constants cannot be modified."); return nullptr; } - if (shader->varyings.has(identifier) && current_function != String("vertex")) { - _set_error("Varyings can only be assigned in vertex function."); - return nullptr; - } assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); if (!assign_expression) { return nullptr; @@ -6260,6 +6325,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } + TkPos name_pos = _get_tkpos(); name = tk.text; if (_find_identifier(nullptr, false, FunctionInfo(), name)) { @@ -6541,11 +6607,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct _set_error("Expected ';'"); return ERR_PARSE_ERROR; } - } else { + } else { // varying ShaderNode::Varying varying; varying.type = type; varying.precision = precision; varying.interpolation = interpolation; + varying.tkpos = name_pos; tk = _get_token(); if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) { @@ -7158,6 +7225,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); } + for (Map<StringName, ShaderNode::Varying>::Element *E = shader->varyings.front(); E; E = E->next()) { + if (E->get().stage == ShaderNode::Varying::STAGE_VERTEX || E->get().stage == ShaderNode::Varying::STAGE_FRAGMENT) { + _set_tkpos(E->get().tkpos); + _set_error(RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'")); + return ERR_PARSE_ERROR; + } + } + return OK; } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 27767378f9..14594b039c 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -41,6 +41,11 @@ class ShaderLanguage { public: + struct TkPos { + int char_idx; + int tk_line; + }; + enum TokenType { TK_EMPTY, TK_IDENTIFIER, @@ -598,10 +603,21 @@ public: }; struct Varying { + enum Stage { + STAGE_UNKNOWN, + STAGE_VERTEX, // transition stage to STAGE_VERTEX_TO_FRAGMENT or STAGE_VERTEX_TO_LIGHT, emits error if they are not used + STAGE_FRAGMENT, // transition stage to STAGE_FRAGMENT_TO_LIGHT, emits error if it's not used + STAGE_VERTEX_TO_FRAGMENT, + STAGE_VERTEX_TO_LIGHT, + STAGE_FRAGMENT_TO_LIGHT, + }; + + Stage stage = STAGE_UNKNOWN; DataType type = TYPE_VOID; DataInterpolation interpolation = INTERPOLATION_FLAT; DataPrecision precision = PRECISION_DEFAULT; int array_size = 0; + TkPos tkpos; Varying() {} }; @@ -780,11 +796,6 @@ private: StringName current_function; bool last_const = false; - struct TkPos { - int char_idx; - int tk_line; - }; - TkPos _get_tkpos() { TkPos tkp; tkp.char_idx = char_idx; @@ -864,6 +875,8 @@ private: bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr); bool _propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat); bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin); + bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message); + bool _validate_varying_using(ShaderNode::Varying &p_varying, String *r_message); Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 9ac66cd4bf..a3c8ef304f 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -242,22 +242,24 @@ RID RenderingServer::_make_test_cube() { RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) { Vector<Vector3> vertices; Vector<Vector3> normals; + const double lat_step = Math_TAU / p_lats; + const double lon_step = Math_TAU / p_lons; for (int i = 1; i <= p_lats; i++) { - double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats); + double lat0 = lat_step * (i - 1) - Math_TAU / 4; double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); - double lat1 = Math_PI * (-0.5 + (double)i / p_lats); + double lat1 = lat_step * i - Math_TAU / 4; double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = p_lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons; + double lng0 = lon_step * (j - 1); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double lng1 = 2 * Math_PI * (double)(j) / p_lons; + double lng1 = lon_step * j; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); @@ -1487,7 +1489,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &RenderingServer::mesh_clear); ClassDB::bind_method(D_METHOD("multimesh_create"), &RenderingServer::multimesh_create); - ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("multimesh_allocate_data", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate_data, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &RenderingServer::multimesh_get_instance_count); ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &RenderingServer::multimesh_set_mesh); ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform", "multimesh", "index", "transform"), &RenderingServer::multimesh_instance_set_transform); @@ -1521,7 +1523,7 @@ void RenderingServer::_bind_methods() { #endif ClassDB::bind_method(D_METHOD("skeleton_create"), &RenderingServer::skeleton_create); - ClassDB::bind_method(D_METHOD("skeleton_allocate", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("skeleton_allocate_data", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate_data, DEFVAL(false)); ClassDB::bind_method(D_METHOD("skeleton_get_bone_count", "skeleton"), &RenderingServer::skeleton_get_bone_count); ClassDB::bind_method(D_METHOD("skeleton_bone_set_transform", "skeleton", "bone", "transform"), &RenderingServer::skeleton_bone_set_transform); ClassDB::bind_method(D_METHOD("skeleton_bone_get_transform", "skeleton", "bone"), &RenderingServer::skeleton_bone_get_transform); @@ -2369,12 +2371,8 @@ RenderingServer::RenderingServer() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1")); GLOBAL_DEF("rendering/volumetric_fog/volume_depth", 128); ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1")); - GLOBAL_DEF("rendering/volumetric_fog/use_filter", 0); + GLOBAL_DEF("rendering/volumetric_fog/use_filter", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)")); - GLOBAL_DEF("rendering/volumetric_fog/directional_shadow_shrink", 512); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/directional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/directional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1")); - GLOBAL_DEF("rendering/volumetric_fog/positional_shadow_shrink", 512); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/positional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/positional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1")); GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10); ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1")); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index fd8d8cd21d..65065841a6 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -367,7 +367,7 @@ public: MULTIMESH_TRANSFORM_3D, }; - virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; + virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0; virtual int multimesh_get_instance_count(RID p_multimesh) const = 0; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0; @@ -409,7 +409,7 @@ public: /* SKELETON API */ virtual RID skeleton_create() = 0; - virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; + virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0; virtual int skeleton_get_bone_count(RID p_skeleton) const = 0; virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0; virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0; @@ -552,7 +552,7 @@ public: virtual RID gi_probe_create() = 0; - virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; + virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0; virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0; virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0; @@ -985,7 +985,7 @@ public: ENV_SDFGI_Y_SCALE_50_PERCENT }; - virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; + virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0; enum EnvironmentSDFGIRayCount { ENV_SDFGI_RAY_COUNT_4, @@ -1025,18 +1025,9 @@ public: virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0; - enum EnvVolumetricFogShadowFilter { - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED, - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW, - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM, - ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH, - }; - - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0; + virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0; virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0; - virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0; - virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0; virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index 5e18dc1e6d..95d2e2254e 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -29,245 +29,89 @@ /*************************************************************************/ #define FUNC0R(m_r, m_type) \ - virtual m_r m_type() { \ + virtual m_r m_type() override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(); \ } \ } -#define FUNCRID(m_type) \ - List<RID> m_type##_id_pool; \ - int m_type##allocn() { \ - for (int i = 0; i < pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - server_name->free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create() { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(); \ - } \ - } - -#define FUNC1RID(m_type, m_arg1) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1); \ - } \ - } - -#define FUNC2RID(m_type, m_arg1, m_arg2) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2); \ - } \ - } - -#define FUNC3RID(m_type, m_arg1, m_arg2, m_arg3) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2, p3); \ - } \ - } - -#define FUNC4RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - int m_type##allocn() { \ - for (int i = 0; i < m_type##_pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create()); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2, p3, p4); \ - } \ +#define FUNCRIDSPLIT(m_type) \ + virtual RID m_type##_create() override { \ + RID ret = server_name->m_type##_allocate(); \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type##_initialize, ret); \ + } else { \ + server_name->m_type##_initialize(ret); \ + } \ + return ret; \ } -#define FUNC5RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - List<RID> m_type##_id_pool; \ - int m_type##allocn(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - for (int i = 0; i < pool_max_size; i++) { \ - m_type##_id_pool.push_back(server_name->m_type##_create(p1, p2, p3, p4, p5)); \ - } \ - return 0; \ - } \ - void m_type##_free_cached_ids() { \ - while (m_type##_id_pool.size()) { \ - free(m_type##_id_pool.front()->get()); \ - m_type##_id_pool.pop_front(); \ - } \ - } \ - virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - if (Thread::get_caller_id() != server_thread) { \ - RID rid; \ - MutexLock lock(alloc_mutex); \ - if (m_type##_id_pool.size() == 0) { \ - int ret; \ - command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \ - SYNC_DEBUG \ - } \ - rid = m_type##_id_pool.front()->get(); \ - m_type##_id_pool.pop_front(); \ - return rid; \ - } else { \ - return server_name->m_type##_create(p1, p2, p3, p4, p5); \ - } \ +//RID now returns directly, ensure thread safety yourself +#define FUNCRID(m_type) \ + virtual RID m_type##_create() override { \ + return server_name->m_type##_create(); \ } #define FUNC0RC(m_r, m_type) \ - virtual m_r m_type() const { \ + virtual m_r m_type() const override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(); \ } \ } #define FUNC0(m_type) \ - virtual void m_type() { \ + virtual void m_type() override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } #define FUNC0C(m_type) \ - virtual void m_type() const { \ + virtual void m_type() const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } #define FUNC0S(m_type) \ - virtual void m_type() { \ + virtual void m_type() override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } #define FUNC0SC(m_type) \ - virtual void m_type() const { \ + virtual void m_type() const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(); \ } \ } @@ -275,560 +119,646 @@ /////////////////////////////////////////////// #define FUNC1R(m_r, m_type, m_arg1) \ - virtual m_r m_type(m_arg1 p1) { \ + virtual m_r m_type(m_arg1 p1) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1); \ } \ } #define FUNC1RC(m_r, m_type, m_arg1) \ - virtual m_r m_type(m_arg1 p1) const { \ + virtual m_r m_type(m_arg1 p1) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1); \ } \ } #define FUNC1S(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) { \ + virtual void m_type(m_arg1 p1) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC1SC(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) const { \ + virtual void m_type(m_arg1 p1) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC1(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) { \ + virtual void m_type(m_arg1 p1) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC1C(m_type, m_arg1) \ - virtual void m_type(m_arg1 p1) const { \ + virtual void m_type(m_arg1 p1) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1); \ } \ } #define FUNC2R(m_r, m_type, m_arg1, m_arg2) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2) { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2); \ } \ } #define FUNC2RC(m_r, m_type, m_arg1, m_arg2) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2); \ } \ } #define FUNC2S(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC2SC(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC2(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC2C(m_type, m_arg1, m_arg2) \ - virtual void m_type(m_arg1 p1, m_arg2 p2) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2); \ } \ } #define FUNC3R(m_r, m_type, m_arg1, m_arg2, m_arg3) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3RC(m_r, m_type, m_arg1, m_arg2, m_arg3) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3S(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3SC(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC3C(m_type, m_arg1, m_arg2, m_arg3) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3); \ } \ } #define FUNC4R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4S(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4); \ } \ } #define FUNC4(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4); \ } \ } -#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \ - } else { \ - server_name->m_type(p1, p2, p3, p4); \ - } \ +#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4); \ + } \ } #define FUNC5R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4, p5); \ } \ } #define FUNC5RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4, p5); \ } \ } #define FUNC5S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ SYNC_DEBUG \ } else { \ + command_queue.flush_if_pending(); \ server_name->m_type(p1, p2, p3, p4, p5); \ } \ } -#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } -#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } -#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5); \ - } \ +#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5); \ + } \ } #define FUNC6R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ + WRITE_ACTION \ if (Thread::get_caller_id() != server_thread) { \ m_r ret; \ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ SYNC_DEBUG \ return ret; \ } else { \ + command_queue.flush_if_pending(); \ return server_name->m_type(p1, p2, p3, p4, p5, p6); \ } \ } -#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ + } + +#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ + } + +#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ } -#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ } -#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6); \ + } \ } -#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ +#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ } -#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6); \ - } \ - } - -#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ - } \ - } - -#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ - if (Thread::get_caller_id() != server_thread) { \ - m_r ret; \ - command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ - SYNC_DEBUG \ - return ret; \ - } else { \ - return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - SYNC_DEBUG \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ - } \ - } - -#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ - } \ - } - -#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ - } \ - } - -#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ - } \ - } - -#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ - } \ - } - -#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ - } \ - } - -#define FUNC14(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ - } \ - } - -#define FUNC15(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14, m_arg15) \ - virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14, m_arg15 p15) { \ - if (Thread::get_caller_id() != server_thread) { \ - command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ - } else { \ - server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ - } \ +#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \ + } \ + } + +#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + m_r ret; \ + command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \ + SYNC_DEBUG \ + return ret; \ + } else { \ + command_queue.flush_if_pending(); \ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + SYNC_DEBUG \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + } + +#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } \ + } + +#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } \ + } + +#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } \ + } + +#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } \ + } + +#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ + } \ + } + +#define FUNC14(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ + } \ + } + +#define FUNC15(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14, m_arg15) \ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14, m_arg15 p15) override { \ + WRITE_ACTION \ + if (Thread::get_caller_id() != server_thread) { \ + command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ + } else { \ + command_queue.flush_if_pending(); \ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ + } \ } diff --git a/tests/data/images/icon.bmp b/tests/data/images/icon.bmp Binary files differnew file mode 100644 index 0000000000..e006f7ebdd --- /dev/null +++ b/tests/data/images/icon.bmp diff --git a/tests/data/images/icon.jpg b/tests/data/images/icon.jpg Binary files differnew file mode 100644 index 0000000000..b45bfa8d9b --- /dev/null +++ b/tests/data/images/icon.jpg diff --git a/tests/data/images/icon.png b/tests/data/images/icon.png Binary files differnew file mode 100644 index 0000000000..45aaaf584f --- /dev/null +++ b/tests/data/images/icon.png diff --git a/tests/data/images/icon.tga b/tests/data/images/icon.tga Binary files differnew file mode 100644 index 0000000000..dcacdc5c67 --- /dev/null +++ b/tests/data/images/icon.tga diff --git a/tests/data/images/icon.webp b/tests/data/images/icon.webp Binary files differnew file mode 100644 index 0000000000..6c4707e858 --- /dev/null +++ b/tests/data/images/icon.webp diff --git a/tests/test_image.h b/tests/test_image.h new file mode 100644 index 0000000000..d73717f5b7 --- /dev/null +++ b/tests/test_image.h @@ -0,0 +1,259 @@ +/*************************************************************************/ +/* test_image.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 TEST_IMAGE_H +#define TEST_IMAGE_H + +#include "core/io/file_access_pack.h" +#include "core/io/image.h" +#include "test_utils.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestImage { + +TEST_CASE("[Image] Instantiation") { + Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_RGBA8)); + CHECK_MESSAGE( + !image->is_empty(), + "An image created with specified size and format should not be empty at first."); + CHECK_MESSAGE( + image->is_invisible(), + "A newly created image should be invisible."); + CHECK_MESSAGE( + !image->is_compressed(), + "A newly created image should not be compressed."); + CHECK(!image->has_mipmaps()); + + Ref<Image> image_copy = memnew(Image()); + CHECK_MESSAGE( + image_copy->is_empty(), + "An image created without any specified size and format be empty at first."); + image_copy->copy_internals_from(image); + + CHECK_MESSAGE( + image->get_data() == image_copy->get_data(), + "Duplicated images should have the same data."); + + PackedByteArray image_data = image->get_data(); + Ref<Image> image_from_data = memnew(Image(8, 4, false, Image::FORMAT_RGBA8, image_data)); + CHECK_MESSAGE( + image->get_data() == image_from_data->get_data(), + "An image created from data of another image should have the same data of the original image."); +} + +TEST_CASE("[Image] Saving and loading") { + Ref<Image> image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8)); + const String save_path_png = OS::get_singleton()->get_cache_path().plus_file("image.png"); + const String save_path_exr = OS::get_singleton()->get_cache_path().plus_file("image.exr"); + + // Save PNG + Error err; + err = image->save_png(save_path_png); + CHECK_MESSAGE( + err == OK, + "The image should be saved successfully as a .png file."); + + // Save EXR + err = image->save_exr(save_path_exr, false); + CHECK_MESSAGE( + err == OK, + "The image should be saved successfully as an .exr file."); + + // Load using load() + Ref<Image> image_load = memnew(Image()); + err = image_load->load(save_path_png); + CHECK_MESSAGE( + err == OK, + "The image should load successfully using load()."); + CHECK_MESSAGE( + image->get_data() == image_load->get_data(), + "The loaded image should have the same data as the one that got saved."); + + // Load BMP + Ref<Image> image_bmp = memnew(Image()); + FileAccessRef f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err); + PackedByteArray data_bmp; + data_bmp.resize(f_bmp->get_len() + 1); + f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_len()); + CHECK_MESSAGE( + image_bmp->load_bmp_from_buffer(data_bmp) == OK, + "The BMP image should load successfully."); + + // Load JPG + Ref<Image> image_jpg = memnew(Image()); + FileAccessRef f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err); + PackedByteArray data_jpg; + data_jpg.resize(f_jpg->get_len() + 1); + f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_len()); + CHECK_MESSAGE( + image_jpg->load_jpg_from_buffer(data_jpg) == OK, + "The JPG image should load successfully."); + + // Load WEBP + Ref<Image> image_webp = memnew(Image()); + FileAccessRef f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err); + PackedByteArray data_webp; + data_webp.resize(f_webp->get_len() + 1); + f_webp->get_buffer(data_webp.ptrw(), f_webp->get_len()); + CHECK_MESSAGE( + image_webp->load_webp_from_buffer(data_webp) == OK, + "The WEBP image should load successfully."); + + // Load PNG + Ref<Image> image_png = memnew(Image()); + FileAccessRef f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err); + PackedByteArray data_png; + data_png.resize(f_png->get_len() + 1); + f_png->get_buffer(data_png.ptrw(), f_png->get_len()); + CHECK_MESSAGE( + image_png->load_png_from_buffer(data_png) == OK, + "The PNG image should load successfully."); + + // Load TGA + Ref<Image> image_tga = memnew(Image()); + FileAccessRef f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err); + PackedByteArray data_tga; + data_tga.resize(f_tga->get_len() + 1); + f_tga->get_buffer(data_tga.ptrw(), f_tga->get_len()); + CHECK_MESSAGE( + image_tga->load_tga_from_buffer(data_tga) == OK, + "The TGA image should load successfully."); +} + +TEST_CASE("[Image] Basic getters") { + Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_LA8)); + CHECK(image->get_width() == 8); + CHECK(image->get_height() == 4); + CHECK(image->get_size() == Vector2(8, 4)); + CHECK(image->get_format() == Image::FORMAT_LA8); + CHECK(image->get_used_rect() == Rect2(0, 0, 0, 0)); + Ref<Image> image_get_rect = image->get_rect(Rect2(0, 0, 2, 1)); + CHECK(image_get_rect->get_size() == Vector2(2, 1)); +} + +TEST_CASE("[Image] Resizing") { + Ref<Image> image = memnew(Image(8, 8, false, Image::FORMAT_RGBA8)); + // Crop + image->crop(4, 4); + CHECK_MESSAGE( + image->get_size() == Vector2(4, 4), + "get_size() should return the correct size after cropping."); + image->set_pixel(0, 0, Color(1, 1, 1, 1)); + + // Resize + for (int i = 0; i < 5; i++) { + Ref<Image> image_resized = memnew(Image()); + image_resized->copy_internals_from(image); + Image::Interpolation interpolation = static_cast<Image::Interpolation>(i); + image_resized->resize(8, 8, interpolation); + CHECK_MESSAGE( + image_resized->get_size() == Vector2(8, 8), + "get_size() should return the correct size after resizing."); + CHECK_MESSAGE( + image_resized->get_pixel(1, 1).a > 0, + "Resizing an image should also affect its content."); + } + + // shrink_x2() + image->shrink_x2(); + CHECK_MESSAGE( + image->get_size() == Vector2(2, 2), + "get_size() should return the correct size after shrink_x2()."); + + // resize_to_po2() + Ref<Image> image_po_2 = memnew(Image(14, 28, false, Image::FORMAT_RGBA8)); + image_po_2->resize_to_po2(); + CHECK_MESSAGE( + image_po_2->get_size() == Vector2(16, 32), + "get_size() should return the correct size after resize_to_po2()."); +} + +TEST_CASE("[Image] Modifying pixels of an image") { + Ref<Image> image = memnew(Image(3, 3, false, Image::FORMAT_RGBA8)); + image->set_pixel(0, 0, Color(1, 1, 1, 1)); + CHECK_MESSAGE( + !image->is_invisible(), + "Image should not be invisible after drawing on it."); + CHECK_MESSAGE( + image->get_pixelv(Vector2(0, 0)).is_equal_approx(Color(1, 1, 1, 1)), + "Image's get_pixel() should return the same color value as the one being set with set_pixel() in the same position."); + CHECK_MESSAGE( + image->get_used_rect() == Rect2(0, 0, 1, 1), + "Image's get_used_rect should return the expected value, larger than Rect2(0, 0, 0, 0) if it's visible."); + + image->set_pixelv(Vector2(0, 0), Color(0.5, 0.5, 0.5, 0.5)); + Ref<Image> image2 = memnew(Image(3, 3, false, Image::FORMAT_RGBA8)); + + // Fill image with color + image2->fill(Color(0.5, 0.5, 0.5, 0.5)); + for (int x = 0; x < image2->get_width(); x++) { + for (int y = 0; y < image2->get_height(); y++) { + CHECK_MESSAGE( + image2->get_pixel(x, y).r > 0.49, + "fill() should colorize all pixels of the image."); + } + } + + // Blend two images together + image->blend_rect(image2, Rect2(Vector2(0, 0), image2->get_size()), Vector2(0, 0)); + CHECK_MESSAGE( + image->get_pixel(0, 0).a > 0.7, + "blend_rect() should blend the alpha values of the two images."); + CHECK_MESSAGE( + image->get_used_rect().size == image->get_size(), + "get_used_rect() should return the expected value, its Rect size should be the same as get_size() if there are no transparent pixels."); + + Ref<Image> image3 = memnew(Image(2, 2, false, Image::FORMAT_RGBA8)); + image3->set_pixel(0, 0, Color(0, 1, 0, 1)); + + //blit_rect() two images together + image->blit_rect(image3, Rect2(Vector2(0, 0), image3->get_size()), Vector2(0, 0)); + CHECK_MESSAGE( + image->get_pixel(0, 0).is_equal_approx(Color(0, 1, 0, 1)), + "blit_rect() should replace old colors and not blend them."); + CHECK_MESSAGE( + !image->get_pixel(2, 2).is_equal_approx(Color(0, 1, 0, 1)), + "blit_rect() should not affect the area of the image that is outside src_rect."); + + // Flip image + image3->flip_x(); + CHECK(image3->get_pixel(1, 0).is_equal_approx(Color(0, 1, 0, 1))); + CHECK_MESSAGE( + image3->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0, 0)), + "flip_x() should not leave old pixels behind."); + image3->flip_y(); + CHECK(image3->get_pixel(1, 1).is_equal_approx(Color(0, 1, 0, 1))); + CHECK_MESSAGE( + image3->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 0)), + "flip_y() should not leave old pixels behind."); +} +} // namespace TestImage +#endif // TEST_IMAGE_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 5c635de25c..2697eb6399 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -46,6 +46,7 @@ #include "test_geometry_2d.h" #include "test_gradient.h" #include "test_gui.h" +#include "test_image.h" #include "test_json.h" #include "test_list.h" #include "test_local_vector.h" diff --git a/tests/test_physics_3d.cpp b/tests/test_physics_3d.cpp index f991fd7c86..74afbad9d1 100644 --- a/tests/test_physics_3d.cpp +++ b/tests/test_physics_3d.cpp @@ -86,7 +86,9 @@ protected: PhysicsServer3D *ps = PhysicsServer3D::get_singleton(); RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape], scenario); - RID body = ps->body_create(p_body, !p_active_default); + RID body = ps->body_create(); + ps->body_set_mode(body, p_body); + ps->body_set_state(body, PhysicsServer3D::BODY_STATE_SLEEPING, !p_active_default); ps->body_set_space(body, space); ps->body_set_param(body, PhysicsServer3D::BODY_PARAM_BOUNCE, 0.0); //todo set space @@ -108,7 +110,9 @@ protected: RID world_margin_shape = ps->shape_create(PhysicsServer3D::SHAPE_PLANE); ps->shape_set_data(world_margin_shape, p_plane); - RID b = ps->body_create(PhysicsServer3D::BODY_MODE_STATIC); + RID b = ps->body_create(); + ps->body_set_mode(b, PhysicsServer3D::BODY_MODE_STATIC); + ps->body_set_space(b, space); //todo set space ps->body_add_shape(b, world_margin_shape); @@ -202,7 +206,8 @@ protected: RID triins = vs->instance_create2(trimesh_mesh, scenario); - RID tribody = ps->body_create(PhysicsServer3D::BODY_MODE_STATIC); + RID tribody = ps->body_create(); + ps->body_set_mode(tribody, PhysicsServer3D::BODY_MODE_STATIC); ps->body_set_space(tribody, space); //todo set space ps->body_add_shape(tribody, trimesh_shape); @@ -358,7 +363,8 @@ public: ps->shape_set_data(capsule_shape, capsule_params); RID mesh_instance = vs->instance_create2(capsule_mesh, scenario); - character = ps->body_create(PhysicsServer3D::BODY_MODE_CHARACTER); + character = ps->body_create(); + ps->body_set_mode(character, PhysicsServer3D::BODY_MODE_CHARACTER); ps->body_set_space(character, space); //todo add space ps->body_add_shape(character, capsule_shape); diff --git a/tests/test_variant.h b/tests/test_variant.h index f8fa852bf4..dfc72b512c 100644 --- a/tests/test_variant.h +++ b/tests/test_variant.h @@ -105,6 +105,600 @@ TEST_CASE("[Variant] Writer and parser float") { CHECK_MESSAGE(b64_float_parsed == 340282001837565597733306976381245063168.0, "Should not overflow."); } + +TEST_CASE("[Variant] Assignment To Bool from Int,Float,String,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant int_v = 0; + Variant bool_v = true; + int_v = bool_v; // int_v is now a bool + CHECK(int_v == Variant(true)); + bool_v = false; + int_v = bool_v; + CHECK(int_v.get_type() == Variant::BOOL); + + Variant float_v = 0.0f; + bool_v = true; + float_v = bool_v; + CHECK(float_v == Variant(true)); + bool_v = false; + float_v = bool_v; + CHECK(float_v.get_type() == Variant::BOOL); + + Variant string_v = ""; + bool_v = true; + string_v = bool_v; + CHECK(string_v == Variant(true)); + bool_v = false; + string_v = bool_v; + CHECK(string_v.get_type() == Variant::BOOL); + + Variant vec2_v = Vector2(0, 0); + bool_v = true; + vec2_v = bool_v; + CHECK(vec2_v == Variant(true)); + bool_v = false; + vec2_v = bool_v; + CHECK(vec2_v.get_type() == Variant::BOOL); + + Variant vec2i_v = Vector2i(0, 0); + bool_v = true; + vec2i_v = bool_v; + CHECK(vec2i_v == Variant(true)); + bool_v = false; + vec2i_v = bool_v; + CHECK(vec2i_v.get_type() == Variant::BOOL); + + Variant vec3_v = Vector3(0, 0, 0); + bool_v = true; + vec3_v = bool_v; + CHECK(vec3_v == Variant(true)); + bool_v = false; + vec3_v = bool_v; + CHECK(vec3_v.get_type() == Variant::BOOL); + + Variant vec3i_v = Vector3i(0, 0, 0); + bool_v = true; + vec3i_v = bool_v; + CHECK(vec3i_v == Variant(true)); + bool_v = false; + vec3i_v = bool_v; + CHECK(vec3i_v.get_type() == Variant::BOOL); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + bool_v = true; + col_v = bool_v; + CHECK(col_v == Variant(true)); + bool_v = false; + col_v = bool_v; + CHECK(col_v.get_type() == Variant::BOOL); +} + +TEST_CASE("[Variant] Assignment To Int from Bool,Float,String,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant int_v = 2; + bool_v = int_v; // Now bool_v is int + CHECK(bool_v == Variant(2)); + int_v = -3; + bool_v = int_v; + CHECK(bool_v.get_type() == Variant::INT); + + Variant float_v = 0.0f; + int_v = 2; + float_v = int_v; + CHECK(float_v == Variant(2)); + int_v = -3; + float_v = int_v; + CHECK(float_v.get_type() == Variant::INT); + + Variant string_v = ""; + int_v = 2; + string_v = int_v; + CHECK(string_v == Variant(2)); + int_v = -3; + string_v = int_v; + CHECK(string_v.get_type() == Variant::INT); + + Variant vec2_v = Vector2(0, 0); + int_v = 2; + vec2_v = int_v; + CHECK(vec2_v == Variant(2)); + int_v = -3; + vec2_v = int_v; + CHECK(vec2_v.get_type() == Variant::INT); + + Variant vec2i_v = Vector2i(0, 0); + int_v = 2; + vec2i_v = int_v; + CHECK(vec2i_v == Variant(2)); + int_v = -3; + vec2i_v = int_v; + CHECK(vec2i_v.get_type() == Variant::INT); + + Variant vec3_v = Vector3(0, 0, 0); + int_v = 2; + vec3_v = int_v; + CHECK(vec3_v == Variant(2)); + int_v = -3; + vec3_v = int_v; + CHECK(vec3_v.get_type() == Variant::INT); + + Variant vec3i_v = Vector3i(0, 0, 0); + int_v = 2; + vec3i_v = int_v; + CHECK(vec3i_v == Variant(2)); + int_v = -3; + vec3i_v = int_v; + CHECK(vec3i_v.get_type() == Variant::INT); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + int_v = 2; + col_v = int_v; + CHECK(col_v == Variant(2)); + int_v = -3; + col_v = int_v; + CHECK(col_v.get_type() == Variant::INT); +} + +TEST_CASE("[Variant] Assignment To Float from Bool,Int,String,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant float_v = 1.5f; + bool_v = float_v; // Now bool_v is float + CHECK(bool_v == Variant(1.5f)); + float_v = -4.6f; + bool_v = float_v; + CHECK(bool_v.get_type() == Variant::FLOAT); + + Variant int_v = 1; + float_v = 1.5f; + int_v = float_v; + CHECK(int_v == Variant(1.5f)); + float_v = -4.6f; + int_v = float_v; + CHECK(int_v.get_type() == Variant::FLOAT); + + Variant string_v = ""; + float_v = 1.5f; + string_v = float_v; + CHECK(string_v == Variant(1.5f)); + float_v = -4.6f; + string_v = float_v; + CHECK(string_v.get_type() == Variant::FLOAT); + + Variant vec2_v = Vector2(0, 0); + float_v = 1.5f; + vec2_v = float_v; + CHECK(vec2_v == Variant(1.5f)); + float_v = -4.6f; + vec2_v = float_v; + CHECK(vec2_v.get_type() == Variant::FLOAT); + + Variant vec2i_v = Vector2i(0, 0); + float_v = 1.5f; + vec2i_v = float_v; + CHECK(vec2i_v == Variant(1.5f)); + float_v = -4.6f; + vec2i_v = float_v; + CHECK(vec2i_v.get_type() == Variant::FLOAT); + + Variant vec3_v = Vector3(0, 0, 0); + float_v = 1.5f; + vec3_v = float_v; + CHECK(vec3_v == Variant(1.5f)); + float_v = -4.6f; + vec3_v = float_v; + CHECK(vec3_v.get_type() == Variant::FLOAT); + + Variant vec3i_v = Vector3i(0, 0, 0); + float_v = 1.5f; + vec3i_v = float_v; + CHECK(vec3i_v == Variant(1.5f)); + float_v = -4.6f; + vec3i_v = float_v; + CHECK(vec3i_v.get_type() == Variant::FLOAT); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + float_v = 1.5f; + col_v = float_v; + CHECK(col_v == Variant(1.5f)); + float_v = -4.6f; + col_v = float_v; + CHECK(col_v.get_type() == Variant::FLOAT); +} + +TEST_CASE("[Variant] Assignment To String from Bool,Int,Float,Vec2,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant string_v = "Hello"; + bool_v = string_v; // Now bool_v is string + CHECK(bool_v == Variant("Hello")); + string_v = "Hello there"; + bool_v = string_v; + CHECK(bool_v.get_type() == Variant::STRING); + + Variant int_v = 0; + string_v = "Hello"; + int_v = string_v; + CHECK(int_v == Variant("Hello")); + string_v = "Hello there"; + int_v = string_v; + CHECK(int_v.get_type() == Variant::STRING); + + Variant float_v = 0.0f; + string_v = "Hello"; + float_v = string_v; + CHECK(float_v == Variant("Hello")); + string_v = "Hello there"; + float_v = string_v; + CHECK(float_v.get_type() == Variant::STRING); + + Variant vec2_v = Vector2(0, 0); + string_v = "Hello"; + vec2_v = string_v; + CHECK(vec2_v == Variant("Hello")); + string_v = "Hello there"; + vec2_v = string_v; + CHECK(vec2_v.get_type() == Variant::STRING); + + Variant vec2i_v = Vector2i(0, 0); + string_v = "Hello"; + vec2i_v = string_v; + CHECK(vec2i_v == Variant("Hello")); + string_v = "Hello there"; + vec2i_v = string_v; + CHECK(vec2i_v.get_type() == Variant::STRING); + + Variant vec3_v = Vector3(0, 0, 0); + string_v = "Hello"; + vec3_v = string_v; + CHECK(vec3_v == Variant("Hello")); + string_v = "Hello there"; + vec3_v = string_v; + CHECK(vec3_v.get_type() == Variant::STRING); + + Variant vec3i_v = Vector3i(0, 0, 0); + string_v = "Hello"; + vec3i_v = string_v; + CHECK(vec3i_v == Variant("Hello")); + string_v = "Hello there"; + vec3i_v = string_v; + CHECK(vec3i_v.get_type() == Variant::STRING); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + string_v = "Hello"; + col_v = string_v; + CHECK(col_v == Variant("Hello")); + string_v = "Hello there"; + col_v = string_v; + CHECK(col_v.get_type() == Variant::STRING); +} + +TEST_CASE("[Variant] Assignment To Vec2 from Bool,Int,Float,String,Vec2i,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant vec2_v = Vector2(2.2f, 3.5f); + bool_v = vec2_v; // Now bool_v is Vector2 + CHECK(bool_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + bool_v = vec2_v; + CHECK(bool_v.get_type() == Variant::VECTOR2); + + Variant int_v = 0; + vec2_v = Vector2(2.2f, 3.5f); + int_v = vec2_v; + CHECK(int_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + int_v = vec2_v; + CHECK(int_v.get_type() == Variant::VECTOR2); + + Variant float_v = 0.0f; + vec2_v = Vector2(2.2f, 3.5f); + float_v = vec2_v; + CHECK(float_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + float_v = vec2_v; + CHECK(float_v.get_type() == Variant::VECTOR2); + + Variant string_v = ""; + vec2_v = Vector2(2.2f, 3.5f); + string_v = vec2_v; + CHECK(string_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + string_v = vec2_v; + CHECK(string_v.get_type() == Variant::VECTOR2); + + Variant vec2i_v = Vector2i(0, 0); + vec2_v = Vector2(2.2f, 3.5f); + vec2i_v = vec2_v; + CHECK(vec2i_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + vec2i_v = vec2_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR2); + + Variant vec3_v = Vector3(0, 0, 0); + vec2_v = Vector2(2.2f, 3.5f); + vec3_v = vec2_v; + CHECK(vec3_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + vec3_v = vec2_v; + CHECK(vec3_v.get_type() == Variant::VECTOR2); + + Variant vec3i_v = Vector3i(0, 0, 0); + vec2_v = Vector2(2.2f, 3.5f); + vec3i_v = vec2_v; + CHECK(vec3i_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + vec3i_v = vec2_v; + CHECK(vec3i_v.get_type() == Variant::VECTOR2); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec2_v = Vector2(2.2f, 3.5f); + col_v = vec2_v; + CHECK(col_v == Variant(Vector2(2.2f, 3.5f))); + vec2_v = Vector2(-5.4f, -7.9f); + col_v = vec2_v; + CHECK(col_v.get_type() == Variant::VECTOR2); +} + +TEST_CASE("[Variant] Assignment To Vec2i from Bool,Int,Float,String,Vec2,Vec3,Vec3i and Color") { + Variant bool_v = false; + Variant vec2i_v = Vector2i(2, 3); + bool_v = vec2i_v; // Now bool_v is Vector2i + CHECK(bool_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + bool_v = vec2i_v; + CHECK(bool_v.get_type() == Variant::VECTOR2I); + + Variant int_v = 0; + vec2i_v = Vector2i(2, 3); + int_v = vec2i_v; + CHECK(int_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + int_v = vec2i_v; + CHECK(int_v.get_type() == Variant::VECTOR2I); + + Variant float_v = 0.0f; + vec2i_v = Vector2i(2, 3); + float_v = vec2i_v; + CHECK(float_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + float_v = vec2i_v; + CHECK(float_v.get_type() == Variant::VECTOR2I); + + Variant string_v = ""; + vec2i_v = Vector2i(2, 3); + string_v = vec2i_v; + CHECK(string_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + string_v = vec2i_v; + CHECK(string_v.get_type() == Variant::VECTOR2I); + + Variant vec2_v = Vector2(0, 0); + vec2i_v = Vector2i(2, 3); + vec2_v = vec2i_v; + CHECK(vec2_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + vec2_v = vec2i_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR2I); + + Variant vec3_v = Vector3(0, 0, 0); + vec2i_v = Vector2i(2, 3); + vec3_v = vec2i_v; + CHECK(vec3_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + vec3_v = vec2i_v; + CHECK(vec3_v.get_type() == Variant::VECTOR2I); + + Variant vec3i_v = Vector3i(0, 0, 0); + vec2i_v = Vector2i(2, 3); + vec3i_v = vec2i_v; + CHECK(vec3i_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + vec3i_v = vec2i_v; + CHECK(vec3i_v.get_type() == Variant::VECTOR2I); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec2i_v = Vector2i(2, 3); + col_v = vec2i_v; + CHECK(col_v == Variant(Vector2i(2, 3))); + vec2i_v = Vector2i(-5, -7); + col_v = vec2i_v; + CHECK(col_v.get_type() == Variant::VECTOR2I); +} + +TEST_CASE("[Variant] Assignment To Vec3 from Bool,Int,Float,String,Vec2,Vec2i,Vec3i and Color") { + Variant bool_v = false; + Variant vec3_v = Vector3(2.2f, 3.5f, 5.3f); + bool_v = vec3_v; // Now bool_v is Vector3 + CHECK(bool_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + bool_v = vec3_v; + CHECK(bool_v.get_type() == Variant::VECTOR3); + + Variant int_v = 0; + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + int_v = vec3_v; + CHECK(int_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + int_v = vec3_v; + CHECK(int_v.get_type() == Variant::VECTOR3); + + Variant float_v = 0.0f; + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + float_v = vec3_v; + CHECK(float_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + float_v = vec3_v; + CHECK(float_v.get_type() == Variant::VECTOR3); + + Variant string_v = ""; + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + string_v = vec3_v; + CHECK(string_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + string_v = vec3_v; + CHECK(string_v.get_type() == Variant::VECTOR3); + + Variant vec2_v = Vector2(0, 0); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + vec2_v = vec3_v; + CHECK(vec2_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + vec2_v = vec3_v; + CHECK(vec2_v.get_type() == Variant::VECTOR3); + + Variant vec2i_v = Vector2i(0, 0); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + vec2i_v = vec3_v; + CHECK(vec2i_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + vec2i_v = vec3_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR3); + + Variant vec3i_v = Vector3i(0, 0, 0); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + vec3i_v = vec3_v; + CHECK(vec3i_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + vec3i_v = vec3_v; + CHECK(vec3i_v.get_type() == Variant::VECTOR3); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec3_v = Vector3(2.2f, 3.5f, 5.3f); + col_v = vec3_v; + CHECK(col_v == Variant(Vector3(2.2f, 3.5f, 5.3f))); + vec3_v = Vector3(-5.4f, -7.9f, -2.1f); + col_v = vec3_v; + CHECK(col_v.get_type() == Variant::VECTOR3); +} + +TEST_CASE("[Variant] Assignment To Vec3i from Bool,Int,Float,String,Vec2,Vec2i,Vec3 and Color") { + Variant bool_v = false; + Variant vec3i_v = Vector3i(2, 3, 5); + bool_v = vec3i_v; // Now bool_v is Vector3i + CHECK(bool_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + bool_v = vec3i_v; + CHECK(bool_v.get_type() == Variant::VECTOR3I); + + Variant int_v = 0; + vec3i_v = Vector3i(2, 3, 5); + int_v = vec3i_v; + CHECK(int_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + int_v = vec3i_v; + CHECK(int_v.get_type() == Variant::VECTOR3I); + + Variant float_v = 0.0f; + vec3i_v = Vector3i(2, 3, 5); + float_v = vec3i_v; + CHECK(float_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + float_v = vec3i_v; + CHECK(float_v.get_type() == Variant::VECTOR3I); + + Variant string_v = ""; + vec3i_v = Vector3i(2, 3, 5); + string_v = vec3i_v; + CHECK(string_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + string_v = vec3i_v; + CHECK(string_v.get_type() == Variant::VECTOR3I); + + Variant vec2_v = Vector2(0, 0); + vec3i_v = Vector3i(2, 3, 5); + vec2_v = vec3i_v; + CHECK(vec2_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + vec2_v = vec3i_v; + CHECK(vec2_v.get_type() == Variant::VECTOR3I); + + Variant vec2i_v = Vector2i(0, 0); + vec3i_v = Vector3i(2, 3, 5); + vec2i_v = vec3i_v; + CHECK(vec2i_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + vec2i_v = vec3i_v; + CHECK(vec2i_v.get_type() == Variant::VECTOR3I); + + Variant vec3_v = Vector3(0, 0, 0); + vec3i_v = Vector3i(2, 3, 5); + vec3_v = vec3i_v; + CHECK(vec3_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + vec3_v = vec3i_v; + CHECK(vec3_v.get_type() == Variant::VECTOR3I); + + Variant col_v = Color(0.5f, 0.2f, 0.75f); + vec3i_v = Vector3i(2, 3, 5); + col_v = vec3i_v; + CHECK(col_v == Variant(Vector3i(2, 3, 5))); + vec3i_v = Vector3i(-5, -7, -2); + col_v = vec3i_v; + CHECK(col_v.get_type() == Variant::VECTOR3I); +} + +TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,Vec3 and Vec3i") { + Variant bool_v = false; + Variant col_v = Color(0.25f, 0.4f, 0.78f); + bool_v = col_v; // Now bool_v is Color + CHECK(bool_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + bool_v = col_v; + CHECK(bool_v.get_type() == Variant::COLOR); + + Variant int_v = 0; + col_v = Color(0.25f, 0.4f, 0.78f); + int_v = col_v; + CHECK(int_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + int_v = col_v; + CHECK(int_v.get_type() == Variant::COLOR); + + Variant float_v = 0.0f; + col_v = Color(0.25f, 0.4f, 0.78f); + float_v = col_v; + CHECK(float_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + float_v = col_v; + CHECK(float_v.get_type() == Variant::COLOR); + + Variant string_v = ""; + col_v = Color(0.25f, 0.4f, 0.78f); + string_v = col_v; + CHECK(string_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + string_v = col_v; + CHECK(string_v.get_type() == Variant::COLOR); + + Variant vec2_v = Vector2(0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec2_v = col_v; + CHECK(vec2_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec2_v = col_v; + CHECK(vec2_v.get_type() == Variant::COLOR); + + Variant vec2i_v = Vector2i(0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec2i_v = col_v; + CHECK(vec2i_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec2i_v = col_v; + CHECK(vec2i_v.get_type() == Variant::COLOR); + + Variant vec3_v = Vector3(0, 0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec3_v = col_v; + CHECK(vec3_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec3_v = col_v; + CHECK(vec3_v.get_type() == Variant::COLOR); + + Variant vec3i_v = Vector3i(0, 0, 0); + col_v = Color(0.25f, 0.4f, 0.78f); + vec3i_v = col_v; + CHECK(vec3i_v == Variant(Color(0.25f, 0.4f, 0.78f))); + col_v = Color(0.33f, 0.75f, 0.21f); + vec3i_v = col_v; + CHECK(vec3i_v.get_type() == Variant::COLOR); +} } // namespace TestVariant #endif // TEST_VARIANT_H |